Howdy,

Using your reproducer: [email protected]:vlsi/mvn-mediation.git at
dd5f3a484634c04fb36da22e931cd51be2a68e6c
using maven master (but revent 4.0.0 would do as well):

[cstamas@angeleyes mvn-mediation (main)]$ mvn -v
Apache Maven 4.1.0-SNAPSHOT (448a6d756351d2b567e498d4087b9637ea69cb0e)
Maven home: /home/cstamas/.sdkman/candidates/maven/latest-master
Java version: 21.0.8, vendor: Eclipse Adoptium, runtime:
/home/cstamas/.sdkman/candidates/java/21.0.8-tem
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.16.12-200.fc42.x86_64", arch: "amd64",
family: "unix"
[cstamas@angeleyes mvn-mediation (main)]$

My local results:
(lib-b-a; unchanged commit hash of your repo)
https://gist.github.com/cstamas/d30b7c682f50ad81c6996fc35d70e317
(lib-a-b; as above but locally altered dep order in example application)
https://gist.github.com/cstamas/7ac9ead53539a3dce88cc154c15faa4b

In this gist above, the first invocation (despite params present, they
are "defaults"), second invocation uses "highest" instead of maven
default "nearest" strategy.

So as you see, in first invocation is as you say:
- guava 33.5 wins
- guice 3.0 wins
= breakage

If I use "highest" strategy, it works, as in this reproducer no direct
deps are involved (maven will never override user instructions):
- guava 33.5 wins as before
- but guice 5.0.1 wins (over 3.0)


So, in this case, as no direct deps override is expected, it works as
expected, no?

Thanks
T

On Wed, Oct 15, 2025 at 1:21 PM Vladimir Sitnikov
<[email protected]> wrote:
>
> 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

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to