A fat JAR is a single JAR file that contains the compiled classes of an application together with all of its dependencies, so the application runs on any machine that has Java installed. In Maven, the Maven Assembly Plugin (maven-assembly-plugin) builds a fat JAR with its predefined descriptor jar-with-dependencies. The same plugin also packages an application in other formats, such as zip, tar, tar.gz and war.
We can control inclusions or exclusions using this plugin. For more controlled packaging, use Maven Shade plugin.
1. A Simple Application
Let us create a simple Java application that prints a log message into the console. To keep things simple, we have included only Log4j2, SLF4J2 and JUnit 5 dependencies.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MainClass
{
private static Logger LOGGER = LoggerFactory.getLogger(MainClass.class);
public static void main( String[] args )
{
LOGGER.info( "Hello World! from Inside a Jar..." );
}
}
2. Including Maven Assembly Plugin
To package this application as a fat JAR, we add the maven-assembly-plugin plugin to the pom.xml file.
2.1. Pre-defined Goal and Descriptors
The assembly plugin has the following two goals.
- help displays help information on the plugin.
- single packages an application bundle or distribution using the assembly descriptor.
The plugin relies on the provided descriptors for controlling the execution and packaging of the project. A descriptor defines what goes into the package and in which format. We can create our own descriptors for custom packaging, and the plugin also provides the following predefined descriptors.
- bin creates a binary JAR produced by running ‘mvn package‘ plus any README, LICENSE, and NOTICE files available in the project root directory.
- jar-with-dependencies creates a JAR that contains the binary output of the project and its unpacked dependencies.
- src packages the contents of the project’s /src directory structure.
- project produces an assembly containing the entire project, minus any build output in /target directory.
2.2. POM Changes
We use the descriptor jar-with-dependencies to create a single package of all the compiled resources. We also set the class MainClass as a manifest entry, so its main() method runs when we run the JAR file from the command line.
Adding the maven-assembly-plugin dependency makes the JAR file larger, because the JAR then includes the plugin JAR and its dependencies. Add the plugin dependency only when the build needs it.
<!-- Optional dependency inclusion -->
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.2</version>
<type>maven-plugin</type>
</dependency>
</dependencies>
<!-- Required plugin declaration -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.howtodoinjava.app.MainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
3. Packaging as Executable Jar
3.1. Default Packaging
Run the maven package command in the project’s root folder to compile and package the project as a fat jar.
$ mvn clean package
The command produces the following two JAR files in the /target folder.
- executable-jar-demo-1.0-SNAPSHOT.jar is a thin JAR that does not include its dependencies, so the JVM searches for the dependencies in the classpath.
- executable-jar-demo-1.0-SNAPSHOT-jar-with-dependencies.jar is the fat JAR and includes all required classes and dependencies. We can run this JAR file on any system where Java is installed.

3.2. Custom Packaging
The name of the fat JAR contains the assembly id (jar-with-dependencies) by default. To remove it, we set the option appendAssemblyId to false.
<configuration>
<appendAssemblyId>false</appendAssemblyId>
...
...
</configuration>
With this option, the plugin produces a single artifact named executable-jar-demo-1.0-SNAPSHOT.jar.
4. Demo
To run the fat JAR, we execute it with the command java -jar from the terminal. In our example, the application prints the log message in the console.

5. Conclusion
The Maven Assembly Plugin packages an application and all of its dependencies into one executable JAR file with the descriptor jar-with-dependencies. The option appendAssemblyId controls the name of the generated file.
Happy Learning !!
For my case when i am trying to create fat jar, its also including jsp and js and images.
Add exclusions under <configuration> tag.
<excludes>
<exclude>**/*.jsp</exclude>
<exclude>**/*.js</exclude>
<exclude>**/*.jpg</exclude>
<!– Add more exclusions if needed –>
</excludes>
If you add the dependency
<dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.4.2</version> <type>maven-plugin</type> </dependency>the fat jar generated is very very fat. It seems it includes all the code for the maven-plugin. But if I just put the version number of the maven-assembly plugin element in the plugin element like this
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.4.2</version> <configuration> <descriptorRefs>the fat jar contains only the code of my application and the code of the java libraries my applications depends on.
Isn’t it better to do it this way ?
Yes, you are correct. When you add the Maven Assembly Plugin as a dependency in your project, it gets included in the generated JAR along with all its dependencies, which can result in a larger JAR file. On the other hand, specifying the plugin directly in the build section of your POM file avoids including the plugin and its dependencies in the final JAR.
Thanks for a good tutorial!
Following these instructions doesn’t create the fat jar for me. Nor do any of the other instructions on the internet relating to make-assembly even if I literally cut and paste the entire mvn pom file and change the names to match my project. Always just creates a single “thin” jar.
To create the fat jar I have to do:
mvn assembly:single
Please make sure that you are adding the <dependency> in <dependencies> section, and not in <dependency-management>.
Actually what did the trick for me was when I found out that I had put the <plugin> within <pluginManagement> which is wrong, it should go into <plugins>, after that it worked like a charm!.