Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven shaded jar used as external project dependency

I have used maven shade plugin in my project to relocate all dependency jar classes under one package e.g., org.shade.*

When I try to use that shaded jar in other application as maven dependency it pulls dependency jar's.

My expectation is when uber/shaded jar included as maven dependency it should not pull any other dependent class jar, Since already those classes are repackaged within shaded jar.

like image 423
erdarun Avatar asked Sep 02 '16 07:09

erdarun


People also ask

What is a shaded jar maven?

maven-shade-plugin : It packages all dependencies into one uber-jar. It can also be used to build an executable jar by specifying the main class. This plugin is particularly useful as it merges content of specific files instead of overwriting them by Relocating Classes.

Why do we need shaded jar?

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.

Are Maven dependencies included in jar?

Apache Maven Shade Plugin provides the capability to package the artifact in an uber-jar, which consists of all dependencies required to run the project.


1 Answers

The classic scenario is:

  • A project producing an uber-jar has its own dependencies (dependency elements in its pom.xml file) which then are packaged together in one uber-jar as Maven artifact
  • When using this uber-jar as a dependency (dependency element) of another project, Maven would then inspect its <artifact>-<version>.pom file (published together with the final artifact into the Maven repository), which is basically a renamed copy of its original pom.xml file, where dependencies (dependency element) were declared (exactly the dependencies packaged into the uber-jar).
  • Since you already have them packed, you would then like to ignore the .pom file (and its dependencies element), for that you need to add exclusions as following:

    <dependency>
        <groupId>com.sample</groupId>
        <artifactId>something-uber</artifactId>
        <version>some-version</version>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

Note: the feature above is only available since Maven 3.2.1.

As such, you are making clear to Maven you don't want any transitive dependency and Maven dependency mediation would then not trigger them.


As a side note: this is not a good practice to have an uber-jar as dependency of a project: it will just make maintenance harder since you can't control transitive dependencies via dependencyManagement or dependencies order of the dependent project. As such you will always need to re-pack the uber jar whenever a dependency (one of its transitive one) would need maintenance (change version and so on) and have much less control on the dependent project (again, harder maintenance).

like image 143
A_Di-Matteo Avatar answered Sep 20 '22 19:09

A_Di-Matteo