Is there a way to create a jar with classes from the current project and a shaded jar containing only external libraries?
I am moving final artifacts over the network and it would be great if I would need to only copy "slim" jar if no external dependencies has changed.
By default Maven will already generate the slim jar you mentioned (that is, a jar providing classes and resources from your project) via the Maven Jar Plugin and by default during the package phase (that is, invoking mvn clean package
, for instance, or mvn clean install
, which in cascade will also invoke the package
phase).
If you want to generate an additional jar only providing the external libraries, for whatever reason, you can use indeed the Maven Shade Plugin. By default however it will also add your project classes and resources.
Applying the configuration below you would instead instruct the plugin to only pack external libraries and skip your project classes and resources:
<build>
<plugins>
<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>${project.groupId}:${project.artifactId}:*</exclude>
</excludes>
</artifactSet>
<finalName>${project.artifactId}-${project.version}-only-dependencies</finalName>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note the exclude
element, which is effectively skipping your project content.
Moreover, the finalName
element needs to be configured in order to avoid the default mechanism of the plugin which will replace the original default jar (mentioned above) with the fat/uber jar (jar + dependencies).
As per official documentation:
The name of the shaded artifactId. If you like to change the name of the native artifact, you may use the setting. If this is set to something different than , no file replacement will be performed
Running mvn clean package
you will then have your default jar file and an additional jar file only containing external dependencies and ending by the only-dependencies
suffix (before the jar extension).
Additionally, you may consider wrapping the whole configuration above in a profile, to avoid having this behavior as part of the default build (recommended).
Just move the configuration above in a wrapping profile as following:
<profiles>
<profile>
<id>assemble-external-jars</id>
<build>
....
</build>
</profile>
</profiles>
And then run it (when required) via:
mvn clean package -Passemble-external-jars