When to use maven jar, maven assembly or maven shade
When it comes to compiling and packaging java application into a jar executable we need to think about external third-party libraries and how to add those inside our application.
We already have build automation tools
Since we have build automation tools like maven things become easier. We have plugins available that we can use when compiling our application.
Is there any plugins that we can use
There are 3 main plugins that we can use when packaging our application into a jar file and those plugins follow different concepts when packaging our application with dependencies.
- maven jar plugin
- maven assembly plugin
- maven shade plugin
Which one
Here are the key concepts that these plugins follow and their use cases.
maven-jar-plugin
: This plugin provides the capability to build and sign jars. But it just compiles the java files under src/main/java and /src/main/resources/. It doesn't include the dependencies JAR files.maven-assembly-plugin
: This plugin extracts all dependency jars into raw classes, and group it together. It can also be used to build an executable jar by specifying the main class. It works in project with less dependencies only, for large project with many dependencies, it will cause Java class name conflict issue.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. This is needed when there are resource files that are have the same name across the jars and the plugin tries to package all the resource files.
How to add
Add configurations mentioned bellow to your project pom file to add plugin support.
Maven Jar Plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>path.to.MainClass</mainClass>
</manifest>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
Maven Assembly Plugin
<build>
<plugins>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>path.to.MainClass</mainClass>
</manifest>
</archive>
</configuration> <executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven Shade Plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation=”org.apache.maven.plugins.shade.resource.ManifestResourceTransformer”>
<mainClass>
path.to.MainClass
</mainClass>
</transformer>
</transformers>
<createDependencyReducedPom>
false
</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven has huge number of plugins available that can be used to extend its features.