Many people who are using the maven-shade-plugin commonly set <createDependencyReducedPom>
to false for reasons beyond my grasp. This is generally a bad idea, as it can lead to problems if you’re writing a library, and has absolutely no advantages.
Here’s a rule of thumbs: If your project shades dependencies, it should create a dependency-reduced-pom.xml.
The situation
Imagine you are currently writing a project called my-library
. It has a few utility classes and also shades another library, which is called someones-third-party-library
.
If you let maven create the dependency-reduced-pom.xml, then all is good and no problems will arise. If however you set <createDependencyReducedPom>
to false in your my-library’s maven-shade-plugin configuration, the following situation will arise:
awesome-skyblock-plugin
now wants to shade my-library
. Maven looks at the pom.xml of my-library
and sees that my-library
depends on someones-third-party-library
. This is called a transitive dependency.
When you now package your awesome-skyblock-plugin, maven will now first of all create a list of dependencies that require to be shaded, which will be:
my-awesome-library
- All dependencies of
my-awesome-library
This means that, although my-library
already contains someones-third-party-library
, maven will include it again (twice!) in your awesome-skyblock-plugin!
The problem
Now two things can happen:
1. You didn’t relocate anything
If you neither relocated someones-third-party-library in my-library, nor relocated my-library in awesome-skyblock-plugin, then you’ll only see a few warnings when compiling awesome-skyblock-plugin
2. You did relocate the dependency
But now imagine that you properly relocated your shaded dependencies: In my-library
, you relocated com.someone.thirdpartylibrary
to my.library.shaded.thirdpartylibrar
y.
If you now compile your awesome-skyblock-plugin, you’ll see that it contains the third-party-library twice:
- The shaded version that’s included in your library, at
my.library.shaded.thirdpartylibrary
- At the original location, coming from the transitive dependency, at
com.someone.thirdpartylibrary
The solution
You need to get rid of the transitive dependency. Maven by default creates a file called dependency-reduced-pom.xml
that is essentially your pom.xml, excluding all dependencies you have already shaded. That means that the original pom.xml of my-library
lists someones-third-party-library
as dependency, but the dependency-reduced-pom.xml will just skip it because you already shaded it, and hence it’s not a dependency for users of my-library anymore.
This is why you should never disable the creation of dependency-reduced-pom.xml.
If you check your pom.xml and find the maven-shade-plugin inside, check if you see the following line somewhere:
<createDependencyReducedPom>false</createDependencyReducedPom> <!-- BAD! Remove this line! -->
If yes: Remove that line! It has no advantages and only leads to problems!
Join my Discord Server for feedback or support. Just check out the channel #programming-help
🙂
I found a very good use for setting that value to true. Buts its very convoluted.
We have a shared jar “core” that we build the normal jar and the shaded version. We deploy the shaded version only to avoid issues with upgrading jars leaving old jar versions at the destination. Thus the use of the “fat” jar. But for builds due to security issues, external jars could become unavailable at a future point. So by using the original jar for subsequent builds, we become aware if a dependency was lost on any of the related projects rather than just the “core” one. But letting maven store the reduced pom, breaks the dependent builds! I realize this leaves us up against someone tinkering with the dependent project and using a newer external jar, but that’s why we review pull requests!