From 67aa392b37fdab6a5e9121b22cb3b89c5d57cc65 Mon Sep 17 00:00:00 2001 From: warku123 Date: Wed, 5 Aug 2026 12:05:40 +0800 Subject: [PATCH 1/2] fix(ci): build multinode test image from the PR's own distribution The multinode CI image step only swapped FullNode.jar into the base image, leaving stale module jars (common, chainbase, ...) from tronprotocol/java-tron:latest on the classpath. Any PR adding a cross-module API then crashes the node at Spring startup with NoSuchMethodError while the container stays Up, surfacing only as 'container tron-mn-node1 is unhealthy' (first hit by PR #82). Build the image lib/ from the PR's own dist zip instead, so all module jars and third-party dependencies come from one dependency resolution. This also auto-adapts to modules being added or renamed and to dependency-version bumps by the PR itself. Also copy /java-tron/logs out of the containers when collecting CI artifacts: docker logs only captures Logback stdout noise, while the real application log (tron.log) lives inside the container, without which node startup failures are undiagnosable. --- .../workflows/integration-test-multinode.yml | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-test-multinode.yml b/.github/workflows/integration-test-multinode.yml index fadfc2168d2..5402d2dc49f 100644 --- a/.github/workflows/integration-test-multinode.yml +++ b/.github/workflows/integration-test-multinode.yml @@ -40,16 +40,30 @@ jobs: key: ${{ runner.os }}-gradle-multinode-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }} restore-keys: ${{ runner.os }}-gradle-multinode- - - name: Build FullNode.jar + - name: Build all java-tron module jars run: ./gradlew clean build -x test --no-daemon - - name: Build local java-tron Docker image (wraps PR-built FullNode.jar) + - name: Build local java-tron Docker image (wraps PR-built jars) run: | + # Build the image from the PR's own distribution: the dist zip's + # lib/ contains every runtime jar this build produces (all module + # jars plus third-party dependencies from one dependency + # resolution). Swapping only FullNode.jar keeps the base image's + # stale jars on the classpath, and the node then dies during Spring + # startup with NoSuchMethodError while the container stays "Up", + # surfacing only as "container tron-mn-node1 is unhealthy". + # Using the dist also auto-adapts to modules being added, renamed, + # or dependency-version bumps by the PR itself. mkdir -p /tmp/tron-image - cp build/libs/FullNode.jar /tmp/tron-image/ + unzip -q framework/build/distributions/java-tron-1.0.0.zip \ + 'java-tron-1.0.0/lib/*' -d /tmp/tron-image + mv /tmp/tron-image/java-tron-1.0.0/lib /tmp/tron-image/lib + rmdir /tmp/tron-image/java-tron-1.0.0 + cp framework/build/libs/FullNode.jar /tmp/tron-image/lib/ cat > /tmp/tron-image/Dockerfile <<'EOF' FROM tronprotocol/java-tron:latest - COPY FullNode.jar /java-tron/lib/FullNode.jar + RUN rm -rf /java-tron/lib + COPY lib/ /java-tron/lib/ EOF docker build -t java-tron-local:pr /tmp/tron-image @@ -101,6 +115,11 @@ jobs: mkdir -p integration-reports/node-logs for c in tron-mn-node1 tron-mn-node2 tron-mn-node3 tron-mn-mongodb; do docker logs "$c" > "integration-reports/node-logs/${c}.log" 2>&1 || true + # docker logs only captures stdout (Logback init noise); java-tron + # writes its real application log to /java-tron/logs/tron.log inside + # the container. Copy it out — without it a node startup failure + # is undiagnosable from CI artifacts. + docker cp "$c":/java-tron/logs/. "integration-reports/node-logs/${c}-applogs/" 2>/dev/null || true done - name: Tear down compose stack From 748f1ea6681c937aec9212f842c5458175e52f7a Mon Sep 17 00:00:00 2001 From: warku123 Date: Wed, 5 Aug 2026 14:11:57 +0800 Subject: [PATCH 2/2] chore(ci): retrigger integration tests to confirm single-node failure reproducibility