Explain Codes LogoExplain Codes Logo

How can I create an executable/runnable JAR with dependencies using Maven?

java
maven-plugin
executable-jar
dependency-management
Alex KataevbyAlex Kataev·Nov 8, 2024
TLDR

Embarking on a JAR-venture? Use the Maven Shade Plugin to create a runnable JAR with all dependencies:

  1. Let's get this party started with this pom.xml snippet:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <!-- Don't forget to check for the latest party favors (version)! --> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- It ain't a party until you plug in the "mainClass"! --> <mainClass>your.package.MainClass</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
  1. Replace your.package.MainClass with your full-of-character entry point.

  2. Now start the party (run the command) mvn package in your terminal.

The result: a self-sufficient executable JAR (target/your-artifactId-version-shaded.jar) ready to run wild with java -jar.

It's a JAR out there! Here's a more detailed journey into creating runnable JARs with Maven.

Fork-in-the-road: Choosing the right plugin

One JAR-solution doesn't fit all, so here are more at your disposal:

  • Maven Shade Plugin: More than meets the JAR, it creates a one-dish JAR, aka "uber JAR" with class relocation for differing dietary preferences (version conflict resolutions).
  • Maven Assembly Plugin: Packs your JAR lunchbox neatly with separate containers for each (dependency). That's my kind of organized chaos!
  • Maven Jar Plugin: For those preferring a variety in a single meal (application), it generates a JAR complete with an external buffet of classes (classpath).

Setting the table: Necessary adjustments

Successful JAR packaging requires some kitchen puns (and adjustments too):

  1. Connect your plugin execution to the life of the party (Maven lifecycle):
<executions> <execution> <!-- 'make-my-jar-with-dependencies' stylized as a haute couture collection --> <id>make-my-jar-with-dependencies</id> <phase>package</phase> <!-- Plugin configuration is a dish best served here --> </execution> </executions>

This ties your packaging with mvn install or mvn package.

  1. Carefully cater to your special guests (files):
    • Use the AppendingTransformer for META-INF/services. It's the VIP lounge for service provider/configuration files!
    • XmlAppendingTransformer for appetizing XML-files, ensuring no byte goes to waste.

Problems on the menu and their culinary solutions:

  • If the JAR fails, check if you've served the correct mainClass and garnished your pom.xml properly.
  • Conflict resolution: shade plugin's transformers are the solution to any neighborhood disputes (file collisions) among your dependencies.
  • Always serve your guests the latest and greatest! Confirm that you're using the updated versions of all the plugins.