Hi devs, Per previous guidance to move this discussion to the mailing list, I’m following up on Maven’s dependency mediation rules (“nearest first” / “declared first”) with a concrete reproducer and a proposal for next steps.
Reproducer: https://github.com/vlsi/mvn-mediation # Background, problem statement In MNG-7852 [1] / issue#9070 [2], I outlined why “nearest/declared first” leads to hard-to-reason classpaths and frequent downgrades of transitives that users cannot practically control (depth/order are effectively random from an application author’s perspective). A real failure we hit: adding dev.sigstore:sigstore-java results in Maven selecting an older protobuf-java at runtime than the one used at compile time. Hervé Boutemy analyzed this case [3] Prior work such as MNG-5988 shows another facet: a test-scoped path can win by being nearer, effectively impacting the compile/runtime classpath which is counterintuitive and risky. The issue text and comments document how a nearer test path overrides a farther compile path, and why that surprises users. # What the reproducer demonstrates With two “third-party” deps that each bring different versions of the same library, the outcome flips based on tree shape or declaration order, producing an incompatible classpath without any explicit signal to the user. The repo has small modules that make this visible with dependency:tree and a tiny runtime check. # Why I believe this is worth revisiting “Nearest/declared first” is predictable to *Maven*, but it’s not *controllable* to end-users unless they redundantly re-declare virtually all transitives (including runtime-only) via dependencyManagement, which is brittle and tends to go stale. It is exactly the failure mode highlighted in MNG-7852 and in Hervé’s analysis. MNG-5988 illustrates that scope semantics (e.g., test vs compile) can be undermined by the current tie-breakers, making production classpaths depend on test paths. # A concrete direction to discuss * Consider all occurrences, then mediate Expand the full graph, then choose a version after seeing all constraints rather than “first mention wins.” This mirrors how many ecosystems approach version resolution. * Migration path / safety rails Provide an experimental switch (resolver/system property) that computes both legacy and proposed results; if they differ, emit a warning showing the two choices and why. I think it would be better to make "highest wins" the default for Maven 4 poms, and it would be great to have a flag for Maven 3 as well Offer a fail-on-divergence mode for CI to surface risky downgrades early. Document how BOMs/depMgmt interact under the new strategy. # Specific questions for the team 1. Would an experimental “consider-all + prefer-highest” mediation behind a flag be acceptable for an initial PR (likely touching Maven Resolver first)? 2. If full “prefer-highest” is too big a jump, what could be the approach to address the issue? I’m happy to iterate on the approach and prototype if this direction sounds reasonable. [1] https://issues.apache.org/jira/browse/MNG-7852 [2] https://github.com/apache/maven/issues/9070 [3] https://github.com/hboutemy/sigstore-maven-plugin/blob/bdf6fbcad0494011c7726456eb61425116a43339/analysis.md Regards, Vladimir
