2

Say my project is called A, and Foo and Bar are third party libraries. A depends on Foo version 1 and Bar. Bar depends on Foo version 2:

A -> Foo version 1  
  \-> Bar  
      \-> Foo version 2

With this Maven shade plugin config in my project's, A's, POM

<relocation>
  <pattern>Foo</pattern>
  <shadedPattern>FooA</shadedPattern>
</relocation>

the version I use, Foo version 1, will be renamed/relocated as FooA.

Question: is it possible to rename/relocate Foo version 2 instead? I know this can be done if I can modify Bar's POM - however, I cannot, since I'm not the distributor of Bar.

flow2k
  • 3,999
  • 40
  • 55
  • Possible duplicate of [Multiple versions of the same dependency in Maven](https://stackoverflow.com/questions/24962607/multiple-versions-of-the-same-dependency-in-maven) – Roland Weisleder Oct 08 '18 at 14:26
  • @RolandWeisleder - thanks for the link - although, I haven't been able to figure out how to apply the answer in that question to my issue - the other question seems to be related but much more general. Could you help? – flow2k Oct 09 '18 at 06:46

1 Answers1

3

Maven does not allow to have a dependency on multiple versions of the same artifact. The dependency resolution works as follows:

Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.

"nearest definition" means that the version used will be the closest one to your project in the tree of dependencies. For example, if dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0.

Source: Introduction to the Dependency Mechanism

Like suggested in this answer the solution could be to produce shaded JARs of each module with such conflicts. With your example, this would be

  • create a module "Bar-shaded" which creates a shaded JAR of "Bar" and all of its dependencies
  • in module "A" add dependencies to "Foo" version 1 and "Bar-shaded"
Roland Weisleder
  • 9,668
  • 7
  • 37
  • 59
  • Ah...by `module "Bar-shaded"` you mean I would need to create another Maven project/artifact (with shade plugin) that acts as a wrapper for the 3rd-party Bar artifact? – flow2k Oct 10 '18 at 18:12
  • 1
    @flow2k Exactly – Roland Weisleder Oct 11 '18 at 06:35
  • It would be so great if the shade plugin had an option which can do this for me automatically, so I don't have to create all these shaded wrapper projects (in case there is more than one). But I guess the feature doesn't exist yet... – flow2k Oct 12 '18 at 21:31