Creating Fat Jars With Gradle and Maven

Deploying Java applications can be challenging, especially when dealing with all the required dependencies to prevent runtime errors. A Fat Jar, also called an Uber Jar, simplifies this process.

What is a Fat Jar?

It is a comprehensive package that includes your Java program and all its necessary dependencies. It bundles everything needed to run your application into a single executable Jar file. This allows the application to operate independently of external libraries, making it portable and easy to execute on any system with a compatible Java Virtual Machine (JVM).

Gradle Shadow Plugin

The Shadow Plugin simplifies creating a Fat Jar in a Gradle-managed Java project by packaging all compiled classes and dependencies into one executable Jar file. It can handle complex dependency trees and relocate classes to resolve version conflicts, making it a valuable tool for Java developers.

Here’s how to set up and use the Shadow Plugin in your Gradle project:

  1. Add the Shadow Plugin to your project: In your build.gradle.kts file (Kotlin DSL), you first need to apply the Shadow plugin. You can do this by adding the following lines:

    plugins {
        id("java")
        id("com.github.johnrengelman.shadow") version "8.1.1"
    }
    
  2. Configure the plugin: After applying the plugin, configure it to set the main class attribute in the Jar’s manifest, which specifies the entry point of your application. This is the class with the main method that will execute when you run the Jar file with the java -jar command. Here’s how you might configure it:

    // The following code snippet configures the shadowJar task to include the Main-Class attribute in the manifest file:
    tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
        manifest {
            attributes["Main-Class"] = "org.alvesfc.FatJarSample"
        }
    }
    // Adding the following line to the build.gradle.kts file will make the shadowJar task depend on the build task:
    tasks.build {
        dependsOn("shadowJar")
    }
    

Maven Shade Plugin

The Maven Shade Plugin is essential for creating a “fat” jar in Maven-based projects, which packages all the project’s compiled classes and runtime dependencies into one executable jar.

Key Features of the Maven Shade Plugin:

  • Uber-Jar Creation: Compiles all project dependencies into a single, runnable jar file, simplifying deployment and execution.
  • Dependency Shading: It can rename (shade) packages of dependencies to avoid conflicts between different versions of the same library.
  • Resource Transformation: The plugin can modify resource files from the project and its dependencies, which is crucial for ensuring that the final jar operates correctly.

Here’s how to set up and use the Maven Shade Plugin in your Maven project:

  1. Add the Maven Shade Plugin to your project: In your pom.xml file, you need to add the Maven Shade Plugin to the build section.

     <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>org.alvesfc.FatJarSample</mainClass>
                                </transformer>
                            </transformers>
                            <!-- Add this filters configuration -->
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    

This configuration sets up the plugin to create an uber-jar during the package phase, shade specific packages to prevent conflicts, and designate the main class for execution. This setup streamlines the creation of a robust, conflict-free, and deployable Java application.

You can find the complete source code of the sample project at this link.

Conclusion

Fat Jars simplifies Java application deployment by packaging all dependencies into one executable file. Developers can easily create these jars using the Gradle Shadow Plugin or Maven Shade Plugin, ensuring applications are portable and consistent across different environments. This method streamlines the deployment process, making it easier and more reliable.

References

Posts in this series