Maven

Maven Shade Plugin Example

In this example we are going to see some of the capabilities from the maven shade plugin.

Maven is a build automation tool used mainly for java projects from apache.

You can access the maven shade plugin here.

We are going to see some examples of the capabilities of the maven shade plugin.

For this example we use the following technologies:

  • MAC OSX
  • Eclipse Mars.1
  • Maven3
  • JDK 1.8.0_65 64bits
  • Maven shade plugin 2.4.3

1. Introduction

The maven shade plugin allow us to generate an uber-jar and allow us to rename the packages of some dependencies. Über is a German word that means above or over. In this case, an uber-jar is an over-jar, in another words, one level up from a simple jar. You can generate one jar that contains your package and all its dependencies in one single jar file. You can distribute your uber-jar as a independent stuff with all its requirements inside of it. The maven shade plugin is beyond maven assembly plugin and is capable to do more things than the maven assembly plugin. The maven shade plugin has one goal defined:

  • shade: Invoked during the package phase

2. Example project

For this example, we are going to use a java project with maven nature that will be packaged as a jar file. Eclipse Mars comes with maven support out of the box, so you don´t have to install anything. Our project will look like this

Example project
Example project

At this point, we have an empty maven project. We are going to define the maven shade plugin inside pom.xml in order to test the plugin capabilities.

The pom.xml will look like this

pom:

<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.javacodegeeks.examples</groupId>
	<artifactId>maven-shade-plugin-example</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>Maven shade plugin ::  example</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.2.2.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.4.3</version>
			</plugin>
		</plugins>
	</build>
</project>

The project has one dummy class called Main. Also, the project defines some dependencies in pom.xml like log4j and spring. In the following bullets, we are going to see some of the maven shade plugin capabilities applied to this project.

3. Include/Exclude dependencies

The plugin allow you to control the dependencies that can be included and excluded in the generated jar. The following pom.xml shows how we can exclude the log4j dependency in the result jar file

pom:

<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.javacodegeeks.examples</groupId>
	<artifactId>maven-shade-plugin-example</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>Maven shade plugin ::  example</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.2.2.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.4.3</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<artifactSet>
								<excludes>
									<exclude>log4j:log4j:jar:</exclude>
								</excludes>
							</artifactSet>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

After running it with mvn package will see an output like this

output:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven shade plugin ::  example 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-shade-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-shade-plugin-example ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven shade plugin/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-shade-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-shade-plugin-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-shade-plugin-example ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-shade-plugin-example ---
[INFO] Building jar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven shade plugin/target/maven-shade-plugin-example-1.0.0-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-shade-plugin:2.4.3:shade (default) @ maven-shade-plugin-example ---
[INFO] Excluding log4j:log4j:jar:1.2.17 from the shaded jar.
[INFO] Including org.springframework:spring-core:jar:4.2.2.RELEASE in the shaded jar.
[INFO] Including commons-logging:commons-logging:jar:1.2 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven shade plugin/target/maven-shade-plugin-example-1.0.0-SNAPSHOT.jar with /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven shade plugin/target/maven-shade-plugin-example-1.0.0-SNAPSHOT-shaded.jar
[INFO] Dependency-reduced POM written at: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven shade plugin/dependency-reduced-pom.xml
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.868 s
[INFO] Finished at: 2016-01-30T00:15:30+01:00
[INFO] Final Memory: 21M/230M
[INFO] ------------------------------------------------------------------------

The generated jar does not include any class from the log4j jar and include all the classes from spring jar. You can see it inside target folder.

You can see more capabilities in order to include/exclude dependencies here.

4. Shading packages

The plugin allows you to shade a package into another package. The following pom.xml shows how we can migrate the classes from com.javacodegeeks package to com.shaded.javacodegeeks. We can use include/exclude tags to define how the migration should work

pom:

<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.javacodegeeks.examples</groupId>
	<artifactId>maven-shade-plugin-example</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>Maven shade plugin ::  example</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.2.2.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.4.3</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<relocations>
								<relocation>
									<pattern>com.javacodegeeks</pattern>
									<shadedPattern>com.shaded.javacodegeeks</shadedPattern>
									<includes>
										<include>com.javacodegeeks.Main</include>
									</includes>
								</relocation>
							</relocations>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

After running mvn package you will find inside the generated jar a new package with the content of the old one, with the includes/excludes instructions applied to it.

  • You can find more details of how use this feature here.

5. Attaching the shaded artifact

The plugin by default will replace the original jar with the shaded jar. You can however generate the shaded jar with a qualifier if you need to distribute both of them. The following pom.xml shows how we can include the shaded jar inside the original jar.

pom:

<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.javacodegeeks.examples</groupId>
	<artifactId>maven-shade-plugin-example</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>Maven shade plugin ::  example</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.2.2.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.4.3</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<shadedArtifactAttached>true</shadedArtifactAttached>
						<shadedClassifierName>jcg</shadedClassifierName>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Now you can see inside target folder a jar with the jcg prefix, you can distribute it in a separate way from the original one.

  • You can find more details of how use this feature here.

6. Conclusions

As we have saw the maven shade plugin offers some interesting capabilities which we can take advantage of in order to build jar files, you can get more details in the link above at the introduction of this example.

7. Download

Download
You can download the full source code of this example here: maven shade plugin

Francisco Hernandez

JEE technologies geek and development engineer. I have over 13 years of experience as software engineer in JEE architectures: Design, development, improvement etc. Currently I work as software architect and consultant. I am mainly involved in projects related to the bank and energy sectors based on Java technologies and Oracle products. I am also very interested in open-source projects
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button