Building Fat JARs with Maven: A Practical Guide to maven-assembly-plugin and maven-shade-plugin

Dec 02, 2025 · Programming · 8 views · 7.8

Keywords: Maven | fat jar | maven-assembly-plugin | maven-shade-plugin | Java packaging

Abstract: This article provides a comprehensive guide to building JAR files with all dependencies included (commonly known as "fat jars" or "uber jars") in Maven projects. It covers two main approaches: using the maven-assembly-plugin and the maven-shade-plugin. The article begins by explaining the need for fat jars, then demonstrates step-by-step configuration for both plugins, including basic dependency bundling, main class setup, runtime classpath configuration, and advanced features like code minimization and dependency relocation. Special attention is given to Spring Boot applications with dedicated configuration recommendations. By comparing the strengths and weaknesses of each approach, it helps developers choose the most suitable solution for their project requirements.

The Need for Dependency-Inclusive JAR Packaging

In Java application development, packaging a project with all its dependencies into a single JAR file (commonly referred to as a "fat jar" or "uber jar") is a widely adopted distribution strategy. The primary advantage of this approach is deployment simplicity—users can launch the application by running just one JAR file, without needing to manage dependency libraries separately. This is particularly beneficial for command-line tools, desktop applications, or server applications that require streamlined deployment processes.

Building Fat Jars with maven-assembly-plugin

The maven-assembly-plugin is an official Apache Maven plugin designed specifically for creating archives that include both project code and all dependencies. It simplifies configuration through predefined descriptors.

To enable maven-assembly-plugin in a project, add the following configuration to the <build> section of the pom.xml file:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

After configuration, executing the mvn package command generates two JAR files: one standard project JAR and another fat jar containing all dependencies, typically named with a "-jar-with-dependencies" suffix.

To ensure the generated fat jar executes correctly, it's usually necessary to configure the main class and classpath. This can be achieved with the maven-jar-plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.example.MainApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Alternative Approach with maven-shade-plugin

The maven-shade-plugin offers another method for building fat jars, providing more advanced features compared to maven-assembly-plugin. Beyond basic dependency bundling, the shade plugin supports:

Here's a basic configuration example for maven-shade-plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.4.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                        <dependencyReducedPomLocation>
                            ${java.io.tmpdir}/dependency-reduced-pom.xml
                        </dependencyReducedPomLocation>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Special Handling for Spring Boot Applications

For Spring Boot applications, the dedicated spring-boot-maven-plugin is recommended, as it includes built-in fat jar construction capabilities. Configuration example:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <mainClass>${start-class}</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

This plugin repackages the project, creating an executable JAR file that contains all dependencies and an embedded web server (if applicable).

Comparison and Selection Guidelines

Both maven-assembly-plugin and maven-shade-plugin have their strengths and weaknesses:

Selection recommendations: For most standard Java applications, maven-assembly-plugin is sufficient; for projects needing package size optimization or dependency conflict resolution, maven-shade-plugin is the better choice; for Spring Boot applications, simply use spring-boot-maven-plugin.

Best Practices and Considerations

When building fat jars, several important considerations should be kept in mind:

  1. Version Management: Always use the latest stable version of plugins, which can be checked via the Maven Central Repository.
  2. Main Class Configuration: Ensure correct main class configuration; otherwise, the generated JAR file cannot be executed directly.
  3. Dependency Conflicts: Conflicts may occur when multiple dependencies contain the same class but different versions. The dependency relocation feature of maven-shade-plugin can help resolve this issue.
  4. File Size: Fat jars can become very large, especially when projects have numerous dependencies. Consider using maven-shade-plugin's code minimization feature to reduce file size.
  5. Testing Validation: After building, always test the generated JAR file to ensure all functionality works correctly.

By appropriately selecting and utilizing these Maven plugins, developers can easily create independently distributable Java applications, simplifying deployment and maintenance workflows.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.