Question
Create an Executable JAR with Dependencies in Maven
Question
I want to package my Java project as a single executable JAR for distribution.
How can I configure a Maven project so that all dependency JARs are included in the final output JAR, making it directly runnable?
Short Answer
By the end of this page, you will understand how Maven creates JAR files, why dependencies are usually not bundled by default, and how to build a single runnable JAR that includes your application's dependencies. You will also learn the most common Maven plugins used for this task, when to use each one, and how to avoid common packaging mistakes.
Concept
In Maven, the default jar packaging creates a JAR containing only your project's compiled classes and resources. It does not automatically unpack and merge dependency JARs into that file.
That is why a normal Maven-built JAR often fails when run alone with:
java -jar myapp.jar
if your application depends on external libraries.
To distribute a Java application as a single runnable file, you usually need an uber JAR or fat JAR. This is a JAR that contains:
- your compiled classes
- your resources
- classes and resources from dependencies
- a manifest entry pointing to the main class
This matters because real applications almost always depend on libraries such as logging frameworks, HTTP clients, JSON parsers, database drivers, and utility packages. If those dependencies are missing at runtime, the application will fail with errors like:
NoClassDefFoundError
ClassNotFoundException
In Maven, the two most common ways to build a runnable JAR with dependencies are:
- Maven Shade Plugin: the most common and flexible option for creating a single merged JAR
- Maven Assembly Plugin: can also create a JAR with dependencies, often simpler but less flexible for advanced cases
For most modern projects, Shade is the preferred choice because it handles class/resource merging more reliably and supports package relocation when dependency conflicts happen.
Mental Model
Think of your application like a lunchbox.
- Your project's compiled code is the main meal.
- Each dependency is a separate side dish in its own container.
- A normal Maven JAR gives you only the main meal.
- A runnable fat JAR packs everything into one box so you can carry and use it anywhere.
Without bundling dependencies, running the app is like showing up with only half the meal. The program starts, looks for a library, and cannot find it.
The Maven plugin's job is to collect all the pieces, put them together, and label the box with instructions saying, "Start from this main class."
Syntax and Examples
Using Maven Shade Plugin
This is the most common way to build a single executable JAR with dependencies.
Add this to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
com.example.Main
Step by Step Execution
Consider this setup:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
Real World Use Cases
Creating an executable JAR with dependencies is common in many real applications:
- Command-line tools: internal utilities, data importers, report generators
- Batch jobs: nightly processing tasks, ETL jobs, scheduled cleanup jobs
- Small services: standalone Java apps launched by scripts or containers
- Desktop launchers: Java-based tools distributed to users
- CI/CD automation tools: build helpers, release scripts, code analysis tools
Example scenarios:
- A team distributes a log-processing tool as one JAR so other teams can run it without manual classpath setup.
- A data migration app uses JDBC and JSON libraries and needs to run as a single deployable file.
- A scheduled background job is copied to a server and started with
java -jarfrom cron or systemd.
In all of these cases, bundling dependencies reduces setup mistakes and makes deployment simpler.
Real Codebase Usage
In real projects, developers usually combine executable JAR packaging with a few common patterns:
Guarding the entry point
The main method often validates required arguments early:
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Usage: java -jar app.jar <input-file>");
return;
}
System.out.println("Processing: " + args[0]);
}
This is an example of an early return or guard clause.
Keeping packaging logic in the build, not the code
Developers usually avoid writing custom scripts to copy JARs around manually. Instead, they configure the build in pom.xml so anyone can run the same command:
mvn clean package
Handling resources and manifests
Applications often need:
- a correct
Main-Class - merged service loader files
- merged framework metadata
This is one reason Shade is popular: it supports resource transformers for these cases.
Using profiles for different packaging needs
Common Mistakes
1. Forgetting to set the main class
If the manifest does not contain the main class, this command will fail:
java -jar myapp.jar
Typical error:
no main manifest attribute
Broken example
<transformers>
</transformers>
Fix
Add a manifest transformer or manifest configuration with the correct fully qualified class name.
2. Using the wrong main class name
The value must include the package.
Broken example
<mainClass>Main</mainClass>
Correct
<mainClass>com.example.Main</mainClass>
3. Expecting the default Maven JAR to include dependencies
This does not happen automatically with the standard maven-jar-plugin.
Broken assumption
Comparisons
| Approach | What it does | Best for | Notes |
|---|---|---|---|
| Default Maven JAR | Packages only your project classes/resources | Libraries and simple artifacts | Not enough for standalone apps with dependencies |
| Maven Assembly Plugin | Builds a JAR with dependencies using predefined descriptors | Simple packaging setups | Easier to start with, less flexible for advanced merging |
| Maven Shade Plugin | Builds a merged executable JAR | Most standalone Java apps | Best choice for fat JARs and dependency/resource handling |
Shade vs Assembly
| Feature | Shade Plugin | Assembly Plugin |
|---|---|---|
| Creates one runnable JAR | Yes | Yes |
Cheat Sheet
Maven executable JAR quick reference
Default behavior
mvn package
- Creates a normal JAR
- Usually does not include dependencies
Shade plugin essentials
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
com.example.Main
FAQ
How do I make a JAR executable in Maven?
Add a plugin such as maven-shade-plugin or maven-assembly-plugin and set the Main-Class in the manifest.
Does mvn package include dependencies by default?
No. The default JAR usually contains only your project's classes and resources.
What is the difference between a fat JAR and a normal JAR?
A normal JAR contains only your app code. A fat JAR also contains dependency classes so it can usually run by itself.
Which Maven plugin should I use for a runnable JAR with dependencies?
For most cases, use maven-shade-plugin. It is the most common option for building a single executable JAR.
Why do I get no main manifest attribute?
Your JAR manifest does not define the Main-Class entry, or it points to the wrong class.
Why do I get ClassNotFoundException after packaging?
Your dependencies were not included, or the wrong plugin/configuration was used.
Can I use provided dependencies in a standalone JAR?
Usually no. provided means the runtime environment is expected to supply them.
Mini Project
Description
Build a small command-line Java application and package it as a single runnable JAR using Maven Shade Plugin. This project demonstrates the exact workflow used in many real applications: write a main class, add a dependency, configure Maven to bundle everything, and run the output with java -jar.
Goal
Create a Maven project that prints a message using a third-party library and package it into one executable JAR with all dependencies included.
Requirements
- Create a Maven Java project with a
Mainclass. - Add at least one external dependency to the project.
- Configure Maven Shade Plugin to set the main class and bundle dependencies.
- Build the project with
mvn clean package. - Run the generated JAR with
java -jar.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.