Create a fat Jar file – Maven Shade Plugin

java jar with maven

In this tutorial, we will show you how to use Maven Shade Plugin to create a Jar together with its dependency Jars into a single executable Jar file, so called fat Jar or uber Jar.

Note
Maven Shade plugin is a better plugin to create fat/uber jar, if compare with assembly plugin, because it provides class relocating feature, to avoid same class name conflict in the classpath.

1. Review a Java project

Previous Java project (dateutils) will be reused, see following folder structure

one-jar-folder-structure
Note
This project has a single dependency – joda-time.jar

2. Pom.xml

Read below comment for self-explanatory.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mkyong.core.utils</groupId>
	<artifactId>dateUtils</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>dateUtils</name>
	<url>http://maven.apache.org</url>

	<properties>
		<jdk.version>1.7</jdk.version>
		<jodatime.version>2.5</jodatime.version>
		<junit.version>4.11</junit.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
			<version>${jodatime.version}</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>dateutils</finalName>
		<plugins>

			<!-- download source code in Eclipse, best practice -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-eclipse-plugin</artifactId>
				<version>2.9</version>
				<configuration>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>false</downloadJavadocs>
				</configuration>
			</plugin>

			<!-- Set a compiler level -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>

		<!-- Maven Shade Plugin -->
		<plugin>
		  <groupId>org.apache.maven.plugins</groupId>
		  <artifactId>maven-shade-plugin</artifactId>
		  <version>2.3</version>
		  <executions>
		     <!-- Run shade goal on package phase -->
		    <execution>
			<phase>package</phase>
			<goals>
				<goal>shade</goal>
			</goals>
			<configuration>
			  <transformers>
				<!-- add Main-Class to manifest file -->
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
					<mainClass>com.mkyong.core.utils.App</mainClass>
				</transformer>
			  </transformers>
			</configuration>
		      </execution>
		  </executions>
		</plugin>

		</plugins>
	</build>

</project>

3. Package It

To produces the final Jar, just package it :


$ mvn package

[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ dateUtils ---
[INFO] Building jar: /Users/mkyong/dateUtils/target/dateutils.jar
[INFO] 
[INFO] --- maven-shade-plugin:2.3:shade (default) @ dateUtils ---
[INFO] Including joda-time:joda-time:jar:2.5 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /Users/mkyong/dateUtils/target/dateutils.jar with /Users/mkyong/dateUtils/target/dateUtils-1.0-SNAPSHOT-shaded.jar
[INFO] Dependency-reduced POM written at: /Users/mkyong/dateUtils/dependency-reduced-pom.xml
[INFO] Dependency-reduced POM written at: /Users/mkyong/dateUtils/dependency-reduced-pom.xml
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.594s
[INFO] Finished at: Tue Oct 21 15:24:28 MYT 2014
[INFO] Final Memory: 17M/42M
[INFO] ------------------------------------------------------------------------

Two jar files will be created in the target folder.

  1. dateutils.jar – Project and dependency classes in a single jar, this is what you want.
  2. original-dateutils.jar – Only your project classes

P.S The generated dependency-reduced-pom.xml is for reference only, just ignore it.

4. Review It

List out the content of dateutils.jar


$ jar tf target/dateutils.jar 

META-INF/MANIFEST.MF
META-INF/
com/
com/mkyong/
com/mkyong/core/
com/mkyong/core/utils/
com/mkyong/core/utils/App.class
META-INF/maven/
META-INF/maven/com.mkyong.core.utils/
META-INF/maven/com.mkyong.core.utils/dateUtils/
META-INF/maven/com.mkyong.core.utils/dateUtils/pom.xml
META-INF/maven/com.mkyong.core.utils/dateUtils/pom.properties
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/
org/joda/
org/joda/time/
org/joda/time/base/
org/joda/time/base/AbstractDateTime.class
org/joda/time/base/AbstractDuration.class
//...
org/joda/time/Weeks.class
org/joda/time/YearMonth$Property.class
org/joda/time/YearMonth.class
org/joda/time/YearMonthDay$Property.class
org/joda/time/YearMonthDay.class
org/joda/time/Years.class
META-INF/maven/joda-time/
META-INF/maven/joda-time/joda-time/
META-INF/maven/joda-time/joda-time/pom.xml
META-INF/maven/joda-time/joda-time/pom.properties
MANIFEST.MF

Manifest-Version: 1.0
Build-Jdk: 1.7.0_05
Built-By: mkyong
Created-By: Apache Maven 3.1.1
Main-Class: com.mkyong.core.utils.App
Archiver-Version: Plexus Archiver

Run it


$ java -jar target/dateutils.jar 

2014-10-21

Download Source Code

Download it – dateUtils-maven-shade-plugin.zip (10 KB)

References

  1. Apache Maven Shade Plugin
  2. Apache Maven Assembly Plugin
  3. Create A Fat Jar File – Maven One-JAR Example
  4. Create a fat Jar file – Maven Assembly Plugin
  5. How to create a jar file with Maven

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
5 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
5 Comment authors
Shivi Goelgopi naikAryasindhu Sahudatriregin Recent comment authors
newest oldest most voted
gopi naik
Guest
gopi naik

hi ,
As i see, shaded plugin will create two jars
1. dateutils.jar
2. original-dateutils.jar

Can we avoid of creating the original-dateutils.jar.
We have a requirement in which we need only the uber jar.

regin
Guest
regin

thanks mkyong! really helpful

Shivi Goel
Guest
Shivi Goel

I have some third party jars which are not part of central repo that i need to include in the executable jar. Currently I have then under project base directory. It seems Maven assembly and shade plugin doesn’t include external dependencies in fat jar. Could you please help if it is possible to build executable jar which is having external libraries included?

Aryasindhu Sahu
Guest
Aryasindhu Sahu

Hi Daitri,

You can achieve this by following these steps :
1) Create a jar using shade plugin, dont include property file in the jar.
2) getResourceAsStream is not required if the file is in the same location as the jar file, use new File(“fileName.extn”);

Check if the jar file is containing all the files you need by opening it in a decompiler, eg JDGui

datri
Guest
datri

I have an uber jar that I am executing with java -jar option, but I also have a requirement to specify -cp option with that command. However, java program is not passing along the value I specify with -cp option to the ClassLoader. How can I make sure that java program passes along the value specified with -cp option to the ClassLoader? I am trying read a properties file from the location specified in the -cp option using the getResourceAsStream method which is failing currently because of this……Any help is much appreciated