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.

Image for post
Image for post

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.

  1. maven jar plugin
  2. maven assembly plugin
  3. maven shade plugin

Which one

Here are the key concepts that these plugins follow and their use cases.

  1. : 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.
  2. : 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.
  3. : 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.

Written by

Undergraduate, Department of Computer Science and Engineering, University of Moratuwa.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store