I have a scenario where-in I need to create an uber jar of a multi module maven project including all modules and their dependencies. I tried using maven shade plugin. but it seems to work only when I use it at the module level. If I add the plugin entry in parent pom then the build breaks (it tries to shade the parent pom)
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing null with C:\Projects\foo.bar\target\foobar-0.0.1-SNAPSHOT-shaded.pom
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error creating shaded jar: null: NullPointerException -> [Help 1]
It does seem to make sense since the <packaging>
for the parent maven project is pom.
But there should be some way to create an uber jar for a multi module project... Any ideas people???
maven-shade-plugin : 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 plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.
Yes ! You can ! :-)
Shade has an implementation problem: it doen't know when is running over pom (not jar or web) project. Pom projects don't generate binary artifacts, then shade doesn't find files to merge, move, etc., throwing NPE.
To solve this problem, create a parent POM from your aggegate-Pom project. Inside it, put the shade definitions and configuration configuring to some profile (eg. alwaysActiveProfiles) and install/deploy it with command:
mvn deploy -P -alwaysActiveProfiles
This command will install this shaded parent without running shade plugin pom (-alwaysActiveProfiles option supress shade plugin execution) and after that, your maven dependent projects will work. Your shaded parent pom could looks like this:
<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>xxxxxxxx</groupId>
<artifactId>web-pom</artifactId>
<name>web-pom</name>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
...
</dependencies>
<profiles>
<profile>
<id>alwaysActiveProfiles</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Remember that your setting.xml must have alwaysActiveProfiles enabled by default, otherwise shade will not run in your dependences shade-pom projects.
You should not be using your parent project's POM file to attempt shading; you should be using a separate aggregator project for this. Parent maven projects are used for inheritance while aggregator projects are used to perform aggregate functions over a group of sub-projects; like shading their JARs together into a uber jar. This project would simply be a pom file at the root directory of your project (the same level as all the sub-modules' folders) which references the sub-projects and has the shade plugin configuration. Make sure the packaing specified for this pom is JAR.
Here is the documentation explaining POM relationships and difference between Aggregation and Inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With