How to use Maven Shade Plugin

Maven Shade Plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade(rename) the packages of some of the dependencies.

This plugin is used to take all the dependencies and extract the content and put them as is and create one big JAR(Uber. This will be good for runnable jar but if you are planning to use this jar as a maven dependency then there may be some conflicts with the client jar. So we need to use the relocations option to relocate the conflicting classes to a different package.

In this post, I will show how to use this plugin with an example.

The below example is for creating the final Uber jar without relocations.

Create Uber Jar without relocations

Consider that we have a web app which exposes a REST web service and running on a grizzly container. Now, let’s use the shade plugin to create the fat jar.

I am not going to give the code examples here as this post explains about the shade plugin only.

Refer the complete code https://github.com/dkbalachandar/greeting-rest

The below plugin configuration has to be added in the maven pom file.

Refer the configuration section where we have to specify various options. They are given below,

  • mainclass – The entry point of the application
  • createSourcesJar – Create the sources jar as well
  • shadedClassifierName – The name of the classifier used in case the shaded artifact is attached
  • shadedArtifactAttached – It defines whether the shaded artifact should be attached as classifier to the original artifact. If its false, then the original jar will be replaced by the shaded jar

    <plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-shade-plugin</artifactId>
	<version>3.1.0</version>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>shade</goal>
			</goals>
			<configuration>
				<createSourcesJar>true</createSourcesJar>
				<shadedClassifierName>shaded</shadedClassifierName>
				<shadedArtifactAttached>true</shadedArtifactAttached>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
						<mainClass>com.Grizzly</mainClass>
					</transformer>
				</transformers>
				<filters>
					<filter>
						<artifact>*:*</artifact>
						<excludes>
							<exclude>META-INF/*.SF</exclude>
							<exclude>META-INF/*.DSA</exclude>
							<exclude>META-INF/*.RSA</exclude>
						</excludes>
					</filter>
				</filters>                          
			</configuration>
		</execution>
	</executions>
</plugin>

Then execute ‘mvn package’ command and then check the target folder. You will be able to see the shaded jar and it ends with shaded suffix. Refer the below screenshot.

shaded-jar

When you extract out the contents of the shaded jar, you will see below.

shaded-jar-extraction

Create Uber Jar with relocations

Now we are going to see how we can relocate some of the classes inside the Uber Jar. Lets use the same example and add the below relocations inside the configuration element.


  <configuration>
	<createSourcesJar>true</createSourcesJar>
	<shadedClassifierName>shaded</shadedClassifierName>
	<shadedArtifactAttached>true</shadedArtifactAttached>
	<transformers>
		<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
			<mainClass>com.Grizzly</mainClass>
		</transformer>
	</transformers>
	<filters>
		<filter>
			<artifact>*:*</artifact>
			<excludes>
				<exclude>META-INF/*.SF</exclude>
				<exclude>META-INF/*.DSA</exclude>
				<exclude>META-INF/*.RSA</exclude>
			</excludes>
		</filter>
	</filters>
	<relocations>
		<relocation>
			<pattern>org.glassfish.grizzly.utils</pattern>
			<shadedPattern>org.shaded.glassfish.grizzly.utils</shadedPattern>
			<excludes>
				<exclude>org.glassfish.grizzly.utils.conditions.*</exclude>
			</excludes>
		</relocation>
	</relocations>
</configuration>

Check the element and the child elements. Here, I am planning to rename/move the org.glassfish.grizzly.utils package to org.shaded.glassfish.grizzly.utils and exclude the package org.glassfish.grizzly.utils.conditions.

Then run the mvn package again to create the shaded jar and extract out the contents of the shaded jar. It will look like below.

shaded-jar-relocations

As you can see that the package org.glassfish.grizzly.utils has been moved to org.shaded.glassfish.grizzly.utils but the inner package org.glassfish.grizzly.utils.conditions has been kept it as in the oringal location.

While relocating the packages, this plugin will also update the affected bytecode. So you will not see any issues while running the Uber jar.