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 thepackage
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
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
You can download the full source code of this example here: maven shade plugin