[ https://issues.apache.org/jira/browse/MNG-8041?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Tamas Cservenak updated MNG-8041: --------------------------------- Fix Version/s: 4.0.0-beta-2 (was: 4.0.0-beta-1) > Maven Core bug regarding resolution scopes for Mojos > ---------------------------------------------------- > > Key: MNG-8041 > URL: https://issues.apache.org/jira/browse/MNG-8041 > Project: Maven > Issue Type: Bug > Components: Artifacts and Repositories > Reporter: Tamas Cservenak > Priority: Major > Fix For: 4.0.0, 4.0.0-beta-2 > > > This bug affects all released Maven versions. > Reproducer: [https://github.com/cstamas/MNG-8041] > Description of the bug: when a Mojo requires Core to collect/resolve given > ResolutionScope, Maven Core does it wrong. Problem is how > LifecycleDependencyResolver and DefaultProjectDependenciesResolver colaborate > plus, how Resolver works. LDR constructs the Resolver filters properly, then > it calls into DPDR, that performs collection. To achieve that, DPDR *blindly* > adds all the POM dependencies to Collect request (which is graph root). But > this is wrong, as this should happen with considering requested (to be > included or to be excluded) scopes. Next what happens, that when collect > request is processed by Resolver, it will contain nodes from unwanted scopes > (as Maven Core blindly added all of them from POM). Just as detail: if > Resolver would be asked to create root, it would NOT add these in the first > place. Due these present, conflict resolver may possibly eliminate other > nodes (as POM ones "always wins", are the closest to graph root. Finally, > these winners may be eliminated in subsequent step, for example due scope > filtering. This results in incomplete resolution scope. > Example: let's consider example where Mojo asks for "runtime" resolution > scope. To serve this, Maven will add ALL dependencies present in POM to > collect request (even those in scopes to be omitted, like "test" scoped > ones), and will perform "collect" using Resolver. When Resolver returns the > graph, it will contain nodes (as 1st level was populated by Maven) that MAY > be contained in deeper nodes of non-test scoped ones (the guice+guava > example). Next, "conflict resolution" happens, and naturally all the "test" > scoped 1st level dependencies will "win", rendering removal of others. > Finally, due "runtime" requested resolution scope, the "test" scoped > dependencies are (rightfully) filtered out. {*}This obviously leads to > incomplete runtime build path{*}. > Or in other words, Maven is wrong here: it adds 1st level dependencies to > CollectRequest that should not be there in the first place (in example above, > the "test" scoped ones), that will cause that Resolver "collect" step build a > graph that has "unwanted" scoped nodes closer to root than actually needed > runtime dependencies (remember: test nodes will be not affected by filter, as > they are already present, added by Maven, and test node children are > collected also as "runtime", just to have "test" scope inherited later in the > process, hence all the children of "test" node will end up in "test" scope, > despite "exclude test" is present!), this will cause that in dependency > conflict resolution step, they will kick out all the rightful runtime > dependencies, and finally, all these winners are removed due scope filter. > Implication of this bug is following important fact: the project "runtime" > resolution scope (as when asked by Mojo) and project "runtime" resolution > scope (as when used as a dependency on some downstream project) {*}were not > the same{*}! > Effects of this bug are explained in "Important Consequences" section of this > page > [https://maven.apache.org/resolver-archives/resolver-2.0.0-alpha-7/common-misconceptions.html#important-consequences] > (that is wrongly written: all that is a consequence of this bug). Also, have > to note, that when this bug get addressed, it will NOT render "workarounds" > broken (ie. introduction of another module just to package "runtime" > classpath using m-assembly-p or alike plugins), just "obsolete", as packaging > of runtime dependencies will become possible in-situ (in the same module of > the project). > Exercises: check out reproducer and execute these commands: > * {{mvn dependency:tree}} => OK, it shows "dependencies included from all > scopes" (this is equiv to "test" build scope), guava is in test scope > * {{mvn dependency:tree -Dscope=runtime}} => NOT OK, it will show effect of > this bug, guava is missing from runtime resolution scope > * install the reproducer project into local repository, and create another > project (or use {{downstream/pom.xml}} from reproducer) that uses reproducer > project as dependency (only one, no depMgt and so on), ask for {{mvn > dependency:tree}} => OK (and look! Guava IS there) -- This message was sent by Atlassian Jira (v8.20.10#820010)