I found the maven-shade-plugin being used in someone’s pom.xml. I’ve never used maven-shade-plugin before (and I’m a Maven n00b) so I tried to understand the reason for using this and what it does.
I looked at the Maven docs, however I can’t understand this statement:
This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade – i.e. rename – the packages of some of the dependencies.
The documentation on the page doesn’t seem very newbie-friendly.
What is an "uber jar?" Why would someone want to make one? What’s the point of renaming the packages of the dependencies? I tried to go through the examples on the maven-shade-plugin apache page such as "Selecting contents for Uber Jar," but I still can’t understand what is being accomplished with "shading."
Any pointers to illustrative examples/use-cases (with an explanation of why shading was required in this case – what problem is it solving) would be appreciated. Lastly, when should I use the maven-shade-plugin?
Uber JAR, in short, is a JAR containing everything.
Normally in Maven, we rely on dependency management. An artifact contains only the classes/resources of itself. Maven will be responsible to find out all artifacts (JARs etc) that the project depending on when the project is built.
An uber-jar is something that takes all dependencies, and extracts the content of the dependencies and puts them with the classes/resources of the project itself, in one big JAR. By having such an uber-jar, it is easy for execution, because you will need only one big JAR instead of tons of small JARs to run your app. It also eases distribution in some cases.
Just a side-note: avoid using uber-jar as a Maven dependency, as it is ruining the dependency resolution feature of Maven. Normally we create an uber-jar only for the final artifact for actual deployment or for manual distribution, but not for putting to Maven repository.
Update: I have just discovered I haven’t answered one part of the question : "What’s the point of renaming the packages of the dependencies?". Here are some brief updates that will hopefully help people having similar questions.
Creating an uber-jar for ease of deployment is one use case of the shade plugin. There are also other common use cases which involve package renaming.
For example, I am developing
Foolibrary, which depends on a specific version (e.g. 1.0) ofBarlibrary. Assuming I cannot make use of other version ofBarlib (because API change, or other technical issues, etc). If I simply declareBar:1.0asFoo‘s dependency in Maven, it is possible to fall into a problem: AQuxproject is depending onFoo, and alsoBar:2.0(and it cannot useBar:1.0becauseQuxneeds to use new feature inBar:2.0). Here is the dilemma: shouldQuxuseBar:1.0(whichQux‘s code will not work) orBar:2.0(whichFoo‘s code will not work)?In order to solve this problem, developer of
Foocan choose to use shade plugin to rename its usage ofBar, so that all classes inBar:1.0jar are embedded inFoojar, and the package of the embeddedBarclasses is changed fromcom.bartocom.foo.bar. By doing so,Quxcan safely depends onBar:2.0because nowFoois no longer depending onBar, and it is using its own copy of the "altered"Barlocated in another package.