Shading a dependency in Maven
Asked Answered
H

1

9

I have two dependencies imported via Maven that both import a common library, but at different versions but the versions are not compatible with each other. Essentially the problem described in this post:

dependency tree

But unfortunately for me, the solution is not as simple as the blog post describes, because there isn't a common version of package Z that works for both dependencies.

Skipping the poor design decisions that led to this point as I don't control any of these libraries, I'm looking to repackage one of the top-level dependencies and shade all of its dependencies so it can essentially use its own, isolated version of Z. Is this possible to accomplish with Maven?

One solution I have considered is isolating all the classes that depend on package Y and putting them in a separate application and shipping that as a shaded jar which X imports, however I'm wondering if there's a simpler way to accomplish that.

Hugibert answered 14/2, 2018 at 8:23 Comment(5)
Have you looked into using Java 9's module system to solve this problem?Saharan
@Saharan Unfortunately, one of the dependencies doesn't support Java 9 yet (as in it doesn't compile) so I don't think that will be an option for me, but I appreciate the pointer, I didn't know about it until now.Hugibert
The pre-java 9 solution would be to apply OSGI, but to modulerize an existing application may be a bit of a leap to begin with. In any case I don't really get your question... you already tagged this with the maven-shade-plugin, one possible solution. So... use it?Saharan
Maybe I'm missing something obvious in the documentation, but how? Everything I've seen on maven-shade-plugin seems to suggest it only allows you to shade the project you're working on, not shade an immediate dependency and its dependencies. I added the tag on the chance that it can do that and somebody knew how, but I guess I do not myself. :(Hugibert
It's a combination of making a fat-jar and shading; fat jarring means packing all the dependency jars into one large jar which you can then distribute. So in your case you could fat-jar module Y and then the old version of Z is packaged into it.Saharan
D
11

As everyone has suggested you can use the maven-shade-plugin. Open source projects handle this by creating one maven sub project for each dependency that needs to be shaded. So in your case you would need 3 maven projects:

  1. One for shading dependency Y
  2. One for shading dependency G
  3. One for your original project. Your original project includes the artifacts created in 1. and 2. as dependencies.

Your maven project hierarchy would look like this:

  • project
    • pom.xml
    • shade-Y
      • pom.xml
    • shade-G
      • pom.xml
    • application
      • pom.xml

An example of a project which has a maven sub project for shading a dependency is here. Look at the shaded-ning19 folder to see how to create a dedicated maven project for shading a dependency.

Davisdavison answered 17/2, 2018 at 7:45 Comment(2)
Awesome, thank you for the example project, that's extremely helpful!Hugibert
Example with poms would be niceArgol

© 2022 - 2024 — McMap. All rights reserved.