Repository navigation
refactor(deps): declare Guava only in consuming modules - #7867
Conversation
Aias00
left a comment
There was a problem hiding this comment.
Review: #7867 refactor(deps): declare Guava only in consuming modules
Reviewed the dependency hygiene change across the multi-module build.
What's good
- Guava is removed from the root
<dependencies>and declared explicitly in the ~40 consuming modules that actually use it (some astest-scoped). This shrinks the dependency surface for modules that don't need Guava and makes Guava usage auditable per module. - The change is mechanical and the module list is comprehensive; the build compiled for the touched modules.
Non-blocking suggestions
- Verify the distribution/assembly (
shenyu-dist, shade/assembly plugins) still bundles Guava wherever it is needed at runtime, since it is no longer inherited transitively from the root. - The latest
pr_buildreports a test failure inshenyu-plugin-tracing, but this PR does not modify that module, and the failure is a surefire test failure (not a Guava compile error), so it looks like a pre-existing flaky test rather than a regression from this refactor. Recommend a re-run ofpr_buildbefore merge to confirm tracing is green.
CI note
The other red jobs (build at ~3s, integrated-test matrix, e2e-case) are infra/network flakiness unrelated to a POM-only change. The core compile + unit tests for the touched modules passed.
Verdict
APPROVE — solid dependency cleanup; please re-run CI to confirm the unrelated tracing flake is green before merging.
The request completion can reach StepVerifier before TracingPlugin.doFinally ends and exports the gateway span. Await a finished span with a bounded timeout before retaining the exact count and parent/trace assertions.
Aias00
left a comment
There was a problem hiding this comment.
Re-review: Approved
Re-approving following commit ae67c7786c (test(tracing): await span export in real HTTP continuity checks).
Verification:
- The asynchronous span export in
TraceContinuityTest#onlyFinishedSpanis now guarded byAwaitility.await(), eliminating the race condition withdoFinallythat caused intermittent test failures. pr_buildcompiles and passes unit tests cleanly (the remaining failures are the known external test fixtures).- Guava dependency cleanup across modules remains clean and modular.
Approved!
Aias00
left a comment
There was a problem hiding this comment.
Re-review after cf2c7498: enumeration looks complete for the modules that actually inherit the root pom
Moving Guava out of the root <dependencies> and into the modules that consume it is the right call - the old arrangement put Guava on the compile classpath of every module in the reactor, including shenyu-spi and shenyu-alert, and made the re2j exclusion a global accident.
I checked completeness rather than trusting the file list, because a miss here is a compile error:
- Code search for
com.google.commonacrossapache/shenyureturns usage inshenyu-admin, the threeadmin-listenermodules,client-core/client-grpc,common,disruptor,infra-redis,kubernetes-controller,loadbalancer, the plugin modules,protocol-grpc/protocol-tcp,register-client-beat/register-client-http,registry-apollo/etcd/zookeeper,sdk-core/feign/spring, the metrics starter, the sync-data modules andshenyu-web- all of which this PR touches. - The modules that use Guava but are not touched do not inherit the shenyu root:
shenyu-e2ehasorg.apache:apache:21as its parent, andshenyu-examplesinheritsspring-boot-starter-parentand pins its ownguava.version. Verified both, so no breakage there. - Scopes match actual usage: the three
admin-listenermodules only import Guava insrc/test, sotestscope is correct;integrated-test-commonuses it inConfUtils(main) and is declared at compile scope. - Moving the
re2jexclusion into<dependencyManagement>is correct - the exclusion now applies to every consumer instead of only to the inherited dependency.
Non-blocking:
shenyu-integrated-test/*poms still inherit the shenyu root, so they are in scope for this change.shenyu-integrated-test-httpand-commonare covered; please confirm the remainingintegrated-testsiblings (sdk-http, dubbo/sofa/tars variants) either do not use Guava or declare it - they are built outside the default reactor, so CI will not tell you.- Worth running
mvn dependency:analyzeonce on the full reactor after this lands; a module that used Guava only transitively will still compile but should declare it.
Same shared-CI-commit note as the sibling PRs: this branch carries the cryptor / SDK-route waits, so rebase after #7970 lands.
Aias00
left a comment
There was a problem hiding this comment.
Requesting changes: this breaks the apache-dubbo integration test at runtime.
Evidence (head cf2c7498, it run 39707739026, job build (shenyu-integrated-test-apache-dubbo)):
Caused by: java.lang.NoClassDefFoundError: com/google/common/collect/Maps
... Factory method 'apacheDubboMetaDataHandler' ... MetaDataHandler
master (80adc159) is green on the same workflow, so the classpath gap is introduced here.
Why: shenyu-integrated-test/pom.xml dropped the compile-scope guava that every IT module used to inherit, and shenyu-integrated-test-apache-dubbo re-added it with <scope>test</scope>. That module is packaged by spring-boot-maven-plugin:repackage and the docker image is built from that fat jar, so a test-scope guava never lands in BOOT-INF/lib, while the gateway still needs Maps during context startup.
Worth checking before choosing the fix: the guava that shenyu-plugin-base and shenyu-plugin-apache-dubbo declare should have covered this transitively, yet it does not reach the repackaged image. Please look at the effective tree:
mvn -pl shenyu-integrated-test/shenyu-integrated-test-apache-dubbo dependency:tree -Dincludes=com.google.guava
Please either
- keep
guavaat compile scope inshenyu-integrated-test/pom.xml(revert that hunk) until every IT module is verified individually, or - declare
guavacompile in the production module that actually references it, and set compile scope on the IT modules that need it at runtime.
Also: 8 of the 12 IT jobs on this run were CANCELLED (sdk-http, grpc, rewrite, https, spring-cloud, combination, tracing, sdk-apache-dubbo), so those are unverified — please re-run the full it matrix after the fix rather than relying on the cancelled jobs.
The rest of the refactor (root <dependencies> → <dependencyManagement>, per-module declarations, re2j exclusion move) still looks correct to me; this is purely about the IT runtime classpath.
Restore compile-scope Guava inheritance for integration applications and remove narrower child declarations so Spring Boot includes Guava at runtime. Targeted starter reactor packaging, the Apache Dubbo IT repackage and dependency trees pass on Java 17. The repackaged jar contains Guava and failureaccess; Maps and ApacheDubboMetaDataHandler initialize from its extracted runtime jars. Full Docker IT execution remains pending.
Include upstream MQTT subscription fixture corrections, preserve the explicit compile-scope Guava dependency in the integration parent, and remove the now-empty common-test dependency block. Validation on Java 17: 151 MQTT tests pass; affected-reactor Checkstyle and Apache RAT pass. Effective POMs confirm compile-scope Guava in all 22 integration projects; all 50 Java-consuming modules retain adequate declarations. The Docker integration matrix is left to CI.
Aias00
left a comment
There was a problem hiding this comment.
Reviewed head 8b4dd57f. The blocking issue from my 2026-10-23 review is fixed and the evidence is now on the record.
Blocker — resolved
shenyu-integrated-test/pom.xml keeps guava at compile scope (version now managed by dependencyManagement), with a comment explaining why: the IT modules are repackaged into executable gateway jars, so a test-scope declaration never reaches BOOT-INF/lib while MetaDataHandler still needs com.google.common.collect.Maps at context startup. That is exactly the first option I offered, and the explanation in the POM means the next person to "clean this up" will know why it is there.
The full matrix confirms it. On this head all nine build (shenyu-integrated-test-*) jobs are green — including apache-dubbo, which was the NoClassDefFoundError: com/google/common/collect/Maps failure, and the eight jobs that were CANCELLED on the earlier run (sdk-http, grpc, rewrite, https, spring-cloud, combination, tracing, sdk-apache-dubbo). Everything else is green too: pr_build, rat_check, sql-matrix, registry_dependencies, build-docker-images, the whole e2e* matrix.
One thing I would like confirmed (not blocking)
The re2j exclusion moved from the root <dependencies> into <dependencyManagement>.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.re2j</groupId>
<artifactId>re2j</artifactId>
</exclusion>
</exclusions>
</dependency>A managed exclusion is applied when guava is a direct declaration of the module, and it travels with the dependency node for transitive edges that pass through such a declaration. It is not applied when guava arrives purely from a third-party path that no shenyu module declares. Previously the root <dependencies> entry made guava a direct dependency of every module with nearest-wins resolution, so the exclusion was effective everywhere.
In practice I expect the outcome is unchanged, because every path I can see goes through shenyu-plugin-base, shenyu-web or shenyu-common, all of which now declare guava and therefore carry the exclusion. But the PR body only records that the two distributions contain exactly one lib/guava-32.0.0-jre.jar and lib/failureaccess-1.0.1.jar — it says nothing about re2j. Could you paste a before/after lib/ listing for admin-bin and bootstrap-bin, or at least confirm re2j is still absent from both? If it did reappear, that is a shipped-jar change that belongs in the description.
Two notes
- The description is ahead of the diff. It describes test fixes for tracing continuity, cryptor configuration errors, SDK 60-second route waits and ZooKeeper backend ports. None of those are in this head: the diff is 49
pom.xmlfiles plus.github/workflows/integrated-test.yml. They were presumably dropped in a later push, but a reader cannot tell, and the accumulated validation log makes the change look much larger and riskier than it is. Please trim it to what actually ships. integrated-test.ymlis an unrelated, good change. Printingdocker compose ps --alland the last 200 log lines before exiting non-zero keeps the gate failing while making an unhealthy-container failure diagnosable. It has nothing to do with dependency scope though — please call it out on its own line in the description, or split it, so it gets reviewed as CI work rather than slipping through under arefactor(deps)title.
Cosmetic
Several POMs end up with a doubled blank line where the new block was inserted, e.g. shenyu-admin-listener-etcd:
</dependency>
+
<dependency>Harmless, but git diff noise across 49 files.
Scope check
I verified the shape of the change rather than every one of the 49 files: root <dependencies> → <dependencyManagement> for guava, version managed centrally, re2j exclusion preserved, per-module declarations split 38 compile / 9 test, shenyu-integrated-test and shenyu-register-protocol handled explicitly. shenyu-common keeping a compile-scope declaration is correct and worth noting — it means downstream consumers still get guava transitively, so the win is hygiene for modules that do not depend on shenyu-common at all, which is what the title claims. No objection there.
Approving. Please answer the re2j question when you get a chance; I do not think it needs another review round.
Fixes #7608. Guava was a compile dependency inherited by every child of the root POM, including modules without Guava usage. Keep its version and the existing re2j exclusion in dependencyManagement, and declare it explicitly in the 50 consuming modules: 38 at compile scope and 12 at test scope. Remove the integrated-test aggregator's duplicate global declaration and the registration protocol's now-unnecessary test-scope override. The examples and E2E reactors have independent parents and are unchanged. Existing legitimate transitive dependencies remain; this change removes unconditional Maven inheritance, not Guava from applications that use it. Validation on Microsoft OpenJDK 17.0.18 through the Maven wrapper: - All 213 default-reactor modules passed clean packaging and main/test compilation with Checkstyle. - The four affected integrated-test modules also passed packaging, test compilation and dependency analysis in a temporary combined reactor with the main repository. Docker integration tests were not executed. - All 50 consuming modules have explicit version-managed declarations with source-appropriate scope. Dependency analysis reported no Guava used-undeclared, unused-declared or scope warnings; unrelated pre-existing dependency warnings remain. - 26 selected SignUtils, SPI loading and extension-loader tests passed with no failures/errors/skips. - Resolved dependency trees contain Guava for shenyu-common and none for shenyu-spi or shenyu-register-protocol. - Apache RAT and git diff --check passed.
sh ./mvnw -B -ntp clean package org.apache.maven.plugins:maven-dependency-plugin:3.8.1:analyze \ -DskipTests -Dmaven.javadoc.skip=true -Djacoco.skip=true -DskipRemoteResources=true ./mvnw -B -ntp -pl shenyu-common,shenyu-spi,shenyu-register-center/shenyu-register-protocol -am test dependency:tree \ -Dtest=SignUtilsTest,ExtensionLoaderTest,SpiLoadFactoryTest -Dsurefire.failIfNoSpecifiedTests=false \ -DskipRemoteResources=true -Djacoco.skip=true -Dmaven.javadoc.skip=true -Dincludes=com.google.guava:guava ./mvnw -B -ntp -N apache-rat:check -DskipRemoteResources=trueThe analysis command explicitly selects dependency-plugin 3.8.1 because the inherited 3.1.1 analyzer cannot read Java 17 class files; no build-plugin version is changed by this PR. Full repository unit-test and Docker E2E execution are left to CI. Review follow-up (October 20): the release-profile Admin and Bootstrap distribution reactor packages successfully on Java 17 (all 163 modules, including test compilation; test execution skipped for packaging). Both generatedadmin-bin.tar.gzandbootstrap-bin.tar.gzcontain exactly onelib/guava-32.0.0-jre.jarandlib/failureaccess-1.0.1.jar. Runtime checks using those extracted jars pass forImmutableList,SettableFuture.set/getand loadingInternalFutureFailureAccess.The previous
pr_buildfailure inTraceContinuityTest.testTheGatewayStartsTheTraceWithoutAnIncomingContextwas reproduced locally. The continuity test now waits, with a five-second bound, for the span thatTracingPlugin.doFinallyexports after request completion. Its existing exact span-count, trace and parent assertions remain. All 71 tracing tests pass, with zero failures/errors/skips; Checkstyle, affected-reactor RAT andgit diff --checkpass. The test fix triggers a fresh CI run; repository permissions prevented re-running the previous workflow directly.CI follow-up on 2026-10-22: merged current master (be34dd1) and added the shared integration-fixture corrections below. The complete 214-module reactor packages successfully on Java 17 with tests skipped and Checkstyle enabled. The previous Dubbo integration failure occurred during compose startup before tests; its job did not retain container diagnostics. GitHub rejected a direct rerun because repository admin rights are required. A new head has been pushed for normal CI.
Shared CI fixture corrections: CryptorResponsePluginTest now checks the post-#7903 configuration error for both encrypt/decrypt when a field is absent, including absence of the original user data. SDK tests wait up to 60 seconds for usable registered routes before exercising assertions. ZooKeeper registration tests keep their declared backend ports reachable so the real health checker cannot race registry-removal assertions. Validation: 16 cryptor unit cases and 16 Admin discovery/health cases pass; the HTTP and SDK integration test reactors compile with Checkstyle. Full Docker integration execution is not claimed: the local Linux Docker engine is unavailable. Remote check results are tracked separately.
Compose startup now prints service state and the last 200 container log lines if startup fails, then exits with failure. Bash syntax validation and git diff --check pass. This preserves the failing gate while making any repeated unhealthy-container failure diagnosable.