Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shading a dependency in Maven

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.

like image 719
kevmo314 Avatar asked Feb 14 '18 08:02

kevmo314


People also ask

How do you shade a dependency?

In Java, to “shade” a dependency is to include all its classes and the classes from its transitive dependencies in your project, often renaming the packages and rewriting all affected bytecode.

What is shading a dependency?

Shading provides a way to include and rename dependencies. It relocates the classes and rewrites affected bytecode and resources to create a private copy of your dependencies.

What does shading mean in Maven?

Shading is a process where a dependency is relocated to a different Java package and copied into the same JAR file as the code that relies on that dependency. The main purpose of shading is to avoid conflicts between the versions of dependencies used by a library and the versions used by the consumers of that library.

How do I exclude a specific version of a dependency in Maven?

Multiple transitive dependencies can be excluded by using the <exclusion> tag for each of the dependency you want to exclude and placing all these exclusion tags inside the <exclusions> tag in pom. xml. You will need to mention the group id and artifact id of the dependency you wish to exclude in the exclusion tag.


1 Answers

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.

like image 135
ilooner Avatar answered Oct 20 '22 06:10

ilooner