Howdy, Here is an issue I initially created for Resolver 2.0.0 to fix some believed bugs, edge cases: https://issues.apache.org/jira/browse/MRESOLVER-391
For impatiens: you can find TL;DR at the end. But so far it turned out that -- while user facing issues do exist -- they stem from littered major (or minor) bugs and problems in several of our core plugins... and all are the result of the same misconceptions. One of the biggest misconceptions is that the project dependency "test" graph is a super set of the "runtime" graph. Out of this misconception is derived another misconception, that one graph can contain multiple classpaths, and by proper partitioning of the graph you can derive this or that (usually "runtime" or "test" classpath). Finally, it seems assumed that a single project (or artifact w/ POM) has one single "tree" (dependency hierarchy). None of these are true, and resolver never worked like that, I believe these are historical remnants from Maven2 times, but this fundamentally changed since the introduction of Resolver (it refined this quite a lot), hence from Maven3, but seems many plugins did not keep up :( What makes these rules non-intuitive, is that in most cases (what we see almost every day) the statements above prove seemingly true. But the so far collected counterexamples (see the issue) are all cases showing that the statements are in reality NOT true and should never be assumed as such. And, the above immediately shows and pinpoints problems in our own plugins (most notably m-dependency-p and m-assembly-p) how they operate along these lines (or, as I see, codebase they use literally "brought over" Maven2 logic, and were never updated properly). I can pinpoint only those two for now, but am afraid there are more. Both of the mentioned plugins operate in a way using the false preconception explained above ("test" graph is a super set of the "runtime" graph). Problem can be easily demonstrated by one of the reproducers and m-dependency-p:tree goal: https://gist.github.com/cstamas/49c21ffd951800af574d8e50e178331c Problems: - Without any param and w/ param -Dscope=test (1st and 2nd invocation) output is identical, so I assume "by default" plugin shows the "test" tree of the project (and that is not documented at all, allowing users to make wrong conclusions). - With -Dscope=runtime (3rd invocation) a very strange thing happens: seemingly the output is correct, but the remark reveals it is not: it mentions a _conflict_ with a version that is defined in "test" scope. As I see by skimming plugin sources, this plugin does exactly the wrong thing: uses "test" graph to cherry pick from it (hence the conflict remark is there). The proper outputs are in fact these (runtime and test graphs, consecutively), as for runtime the test scoped dependencies are ignored, hence conflict exists ONLY in test graph and not in runtime graph: [INFO] org.acme:acme-product-a:jar:1.0.0-SNAPSHOT [INFO] \- org.acme:acme-lib-b:jar:1.0.0-SNAPSHOT [compile] [INFO] \- org.acme:acme-lib-c:jar:1.0.0-SNAPSHOT [compile] [INFO] org.acme:acme-product-a:jar:1.0.0-SNAPSHOT [INFO] +- org.acme:acme-lib-d:jar:1.0.0-SNAPSHOT [test] [INFO] | \- org.acme:acme-lib-c:jar:2.0.0-SNAPSHOT [compile] [INFO] \- org.acme:acme-lib-b:jar:1.0.0-SNAPSHOT [compile] [INFO] \- org.acme:acme-lib-c:jar:1.0.0-SNAPSHOT [compile] (conflicts with 2.0.0-SNAPSHOT) In short, all these issues show that these plugins contain false preconceptions. Hence, for Maven4 plugins I think it would be more correct for us to "bite the bullet" and redo major core plugins correctly, instead to "port" them (with their false preconceptions). Moreover, regarding assembly plugin, these subtle but real bugs are the reasons why alternate replacements exist, like the proviso plugin (used by mvnd) that is actually "assembly plugin done right". And to make a small "detour" to Maven 3.9 introduced plugin validation (where use of `ArtifactRepository` in Mojo parameter was a clear indicator of legacy code): very same stands for type `org.apache.maven.project.ProjectBuildingRequest`: whenever you see this type (mis)used in session-like constructs (when it is clear it is MavenSession or RepositorySystemSession should be used here), it is a clear indicator you deal with a legacy code. Never use such code for new features, but do it right instead. === tl;dr: Never assume that the "test" graph is a superset of the "runtime" graph, it is NOT (it WAS in Maven2). Code assuming this is BAD CODE. Legacy code (coming from Maven2 age) does it wrong, and this just makes me convinced more that we should just get rid of legacy (instead of spending energy on fixing it), as it explicitly prevents us not only to advance forward, but also prevents us to fix issues like these (as the whole codebase is done in Maven2 way, at least in assembly and dependency plugins w/ all their downstream deps like dep-tree is). These fundamental issues were also the reason why "alternate" plugins popped up, like proviso, that is a replacement for assembly plugin "done right". Maybe Maven4 plugins (using Maven4 API) is the time to really "redo" the plugins correctly, and not "port them" to new APIs, as it will port these wrong assumptions as well. Thanks T