Howdy, Let's put aside discussion about _correctness_ or _righfulness_ of having duplicated classpath entries for start, and talk about classpath ordering only... Also, this below discusses Maven Core ONLY, as there are some plugins out there doing similar things, and Maven Core cannot affect them (as they usually go directly for Resolver APIs).
Currently in the "stable" Maven 3.x line, there are several spots where classpath (list of artifacts) is being created. They are unrelated (more correctly, there are several spots doing pretty much the same thing), but in general, ordering is happening as this: * effective POM/model is being built (and even in this step you have "quirks", see https://issues.apache.org/jira/browse/MNG-7854 and PR https://github.com/apache/maven/pull/1211) and reproducer https://github.com/cstamas/MNG-7852, repo name is wrong, this is MNG-7854 reproducer) * Based on the model, the graph is built in resolver ("collect" step). The graph is "ideally" a tree, but does not have to be, it can have cycles, maybe a forest, etc. * some transformation/mediation/elimination is applied ("maven rules" like nearest-wins, exclusions, scope filtering, etc) * artifacts are resolved ("resolve" step), basically each artifact at the end points to one File in local repo * the graph is being transformed into List<Artifact> (or directly into List<File>) So far we can see that the graph is somewhat affected by ordering in the model, so basically HOW you order your dependencies in your POM does matter. Still, there are some unexpected quirks. And here comes the interesting bit: Maven 3.x uses ALWAYS pre-order processing, see issue https://issues.apache.org/jira/browse/MNG-6357 , there is a reproducer by Tomo Suzuki, also at the end there my "results''. An in-order transformation of a graph into a list has its own shortcomings, not to mention how it is "currently put in concrete", no way to change it, and it is not always what the user wants. Hence, I went with an "experiment": created https://issues.apache.org/jira/browse/MRESOLVER-390 and PR https://github.com/apache/maven-resolver/pull/322 that extends resolver in several ways: aside of "classic" pre-order, I introduced "level-order" (as asked by users) and "post-order" (just for fun, unsure who would want it) processing, as resolver currently offers NOTHING aside of pre-order. Second, I integrated this patch into Maven here https://github.com/apache/maven/pull/1212 that as title says, REMOVES any ordering code from Maven (pretty much duplicated code) and it always delegates to Resolver, that is in turn, properly configured via Resolver Session. Consider all these code changes as PoC only, they were just an "experiment" as I was tinkering about CP ordering. Still, the code does work as expected. TL;DR * POM ordering matters (maybe in a bit of an non-intuitive way), that produces a graph that is processed ALWAYS (in Maven 3) in a pre-order way. * see Tomo Suzuki reproducer: https://issues.apache.org/jira/browse/MNG-6357?focusedCommentId=16824520&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-16824520 here Maven 3 produces (probably a bit unexpected) order: artifact1, artifact4, artifact2, artifact5, artifact3 - typical pre-order * level-order may be something that makes things more intuitive... Thanks T On Tue, Aug 29, 2023 at 7:09 PM David Karr <davidmichaelk...@gmail.com> wrote: > I support a large number of SpringBoot services built with Maven. > > I recently noticed that one of our transient dependencies has a conflict > with another transient dependency, as it has several FQCNs that are > identical to ones in the second artifact, but with different content. In > most of those services, the first artifact ended up in the classpath after > the second artifact, so the "good" version of those classes was obtained > from the second artifact. > > In a couple of services, the order was reversed, causing fatal startup > problems. > > I thought perhaps that if I moved the "top-level" dependency that > references the transient artifact to the bottom of the dependencies list in > the pom.xml, it might control where that transient artifact ends up in the > classpath. This unfortunately had no effect. It's possible this has an > effect on the ordering of the "top-level" dependencies, but it didn't do > anything for the transient dependencies. > > I had thought that perhaps fixing this required changing the SpringBoot > "classpath.idx" file that specifies the order that SpringBoot would load > dependencies, so I created this issue: > https://github.com/spring-projects/spring-boot/issues/37125 > > However, I think the responder is correct that the ordering in this file > really should reflect the "Maven view" of dependency ordering. > > In the particular case where this came up, I have resolved the problem the > only way available to me, which is simply editing the problematic jar, > removing the FQCNs that are duplicates, and creating a new artifact that > services will use instead of the original jar. This is obviously a hack, > and might not be possible in other situations. >