Creating a Fat Jar App with Spring Boot

In this guide, I’ll show you how to create a Fat Jar with Spring Boot. Together, we’ll build a simple ‘UsersMicroservice’, then pack it into a Fat Jar. Don’t worry if you’re new, I’ll guide you step-by-step and answer your top questions along the way. Let’s get started!

What is a Fat JAR?

A Fat JAR, also commonly referred to as an uber-JAR, is a Java ARchive (JAR) file that includes not only the application’s compiled source code, but also all of its dependencies and resources required to run the application. These dependencies can include libraries, frameworks, and even the embedded server such as Tomcat or Jetty, which are often used in Spring Boot applications.

In other words, a fat JAR is a self-contained package. Unlike a regular JAR file, which may require external dependencies to be present in the classpath when running the application, a fat JAR is fully self-sufficient and can be run on any system that has Java Virtual Machine (JVM) installed, without the need to install or set up any additional dependencies.

Why Create a Fat JAR?

Creating a fat JAR has several advantages:

  1. Simplicity: Since a fat JAR contains everything needed to run your application, it simplifies the deployment process. There is no need to worry about setting up and managing external dependencies on the deployment environment.
  2. Portability: You can run a fat JAR on any platform that supports the JVM. This makes it extremely portable and well-suited for various environments, including different development, testing, staging, and production setups.
  3. Microservices Architecture: Fat JARs are particularly useful in a microservices architecture. In this architectural style, each microservice is often a self-contained application that can be developed, deployed, and scaled independently. Packaging each microservice as a fat JAR makes it easy to manage and deploy each service separately.
  4. Consistency: When you package your application as a fat JAR, you’re ensuring that the same set of dependencies is used both during the build and when the application is running. This can help to avoid issues that can arise when different versions of dependencies are used at build and run time.

Despite these advantages, it’s also important to be aware of the downsides of fat JARs. They can be significantly larger than regular JARs, which can slow down build and startup times and use more resources. Additionally, if multiple fat JARs on the same system use the same dependencies, this can lead to redundancy, as each JAR includes its own copy of each dependency.

Create your project

Start by creating a new Spring Boot project. You can use the Spring Initializr to do this. Make sure to include the necessary dependencies. Here, we’ll just use Spring Web for simplicity.

Create Application Classes

Now, let’s create the application classes. For this example, I’ll create a model class named User and a REST controller named UsersController. However, these are just for demonstration purposes and do not directly relate to the creation of a fat JAR. In your case, the classes will likely differ based on your application’s specific needs.

Model Class: Create a User class under src/main/java/com/example/UsersMicroservice/model.

package com.example.UsersMicroservice.model;

public class User {
    private String name;
    private String email;
    // constructor, getters, and setters
}

Controller Class: Next, create a UsersController class under src/main/java/com/example/UsersMicroservice/controller.

package com.example.UsersMicroservice.controller;

import com.example.UsersMicroservice.model.User;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(path = "/users")
public class UsersController {
    
    @PostMapping
    public User create(@RequestBody User user) {
        // save the user
        return user;
    }
}

Remember, these classes serve as an example and the actual application classes you need to create will depend on your specific application’s requirements.

Maven Dependencies in pom.xml

In this section, we will explain how to set up your pom.xml file with the appropriate Maven dependencies for creating a Spring Boot RESTful microservice application which will be packed into a Fat Jar.

Dependencies Section

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

In the dependencies section, we specify the libraries that our project needs to run. In this case, I have included the spring-boot-starter-web dependency.

The spring-boot-starter-web is a starter for building web applications and Microservices. It uses Tomcat as the default embedded container.

When we add this dependency, Maven automatically downloads it and makes it available for our project. It ensures our application has all the necessary modules to create a web-based application.

Build Section

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

The build section is where we specify build-related settings. The most crucial aspect here is the spring-boot-maven-plugin. This plugin provides several features:

  1. It creates an executable jar or war file. This is what we refer to as a “fat jar” because it includes all the dependencies and files required to run the application. This makes it easier to distribute and deploy your application.
  2. It searches for the public static void main(String[] args) method to flag as a runnable class.
  3. It provides a built-in dependency resolver that sets the version number to match Spring Boot dependencies. So, you can leave out version tags for your dependencies.

In summary, spring-boot-starter-web is necessary for creating web-based applications, including RESTful services. On the other hand, spring-boot-maven-plugin is critical in packaging your application and its dependencies into a single, executable “fat” jar, thereby simplifying the distribution and deployment process.

Building a Fat Jar with Maven

Alright, let’s dive into the main part of this process – building a Fat Jar for our application. Don’t worry if this feels a bit daunting; we’re going to take it step-by-step, and I promise you it’s easier than it seems.

Execute mvn clean package command

Alright, now let’s dive into the process of creating our Fat Jar. First, we need to run a specific command in our terminal. Navigate to the project directory and type the following command: mvn clean package.

This command does a couple of things.

  • mvn clean will clean up any artifacts created from previous builds. After that,
  • mvn package kicks in. This command takes our project and packages it according to its pom.xml configuration – in our case, into a Fat Jar.

Once you run the command, you’ll see a bunch of output in your terminal. Don’t worry if it seems a bit overwhelming – it’s Maven telling you what it’s doing at each step. You’ll see it compile your code, run any tests, and then package your code into a jar file.

The last line of the output should be a success message indicating that your Fat Jar has been created. It will look something like this:

[INFO] Building jar: /path-to-your-project/target/UsersMicroservice-1.0.0.jar

You’ll find your Fat Jar in the target directory of your project. The jar file will be named in the format [artifactId]-[version].jar, as defined in your pom.xml file.

Executing Your Fat Jar Locally

Now, how do we run this Fat Jar? It’s actually pretty straightforward. Since the Fat Jar is an executable jar, you can run it using the java -jar command. Navigate to the target directory and run java -jar UsersMicroservice-1.0.0.jar.

You should see your Spring Boot application starting up, and it should be accessible at the configured port (usually localhost:8080 for default configurations). You can now test your application’s functionality to make sure everything works as expected.

Debugging Your Fat Jar Build Process

Sometimes, things don’t go as smoothly as we’d like. If you encounter issues while creating your Fat Jar, don’t worry. Here are a few steps to help you debug:

  1. Check your pom.xml file: Ensure all the necessary dependencies and plugins are included and correctly configured.
  2. Look at the Maven output: If there’s a problem, Maven will usually tell you in its output. Check for any error messages.
  3. Run with Debug option: You can run Maven with the -X option (i.e., mvn -X clean package) to get more detailed output which can help identify any issues.
  4. Reach out: There’s a large community of Spring Boot developers out there. If you’re stuck, don’t hesitate to ask for help on platforms like StackOverflow.

Remember, it’s okay to encounter issues during the process – it’s a part of learning. Just take one step at a time and you’ll get there.

How to Exclude or Include Dependencies in Your Fat Jar

Alright, let’s talk about managing dependencies in our Fat Jar. You might be wondering – why would we want to include or exclude certain dependencies? Well, sometimes you might want to leave out a certain dependency that’s already provided by your runtime environment, or you may want to avoid version conflicts. On the other hand, ensuring necessary dependencies are included is vital to having your application run correctly.

Including Dependencies

By default, when you package your Spring Boot application into a Fat Jar, all the project’s dependencies as specified in the pom.xml file are included in the jar. This means that if your application depends on a certain library, Spring Boot will make sure it’s packaged into the Fat Jar.

It’s worth noting that this happens automatically – you don’t need to do anything special to include dependencies. As long as you’ve correctly specified your dependencies in the pom.xml file, Spring Boot’s Maven plugin takes care of the rest.

Excluding Dependencies

There may be situations where you’d want to exclude a specific dependency from your Fat Jar. For instance, you might want to exclude a certain library because it’s already provided by the environment where your application will be running.

To exclude a dependency, you can do so in the pom.xml file. Here’s an example of how to do this:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

In this example, the spring-boot-starter-tomcat dependency is being excluded from the spring-boot-starter-web dependency. This would be useful if your application will be running in an environment where Tomcat is already provided.

Please remember, when you exclude a dependency, you need to ensure that it will be available at runtime by some other means. Otherwise, your application might not work correctly.

Summary

Congratulations on building your Fat Jar application with Spring Boot using Maven! This is a crucial skill for creating distributable and deployable Spring Boot applications.

Here are the key takeaways from this tutorial:

  • Maven Project Setup: You started by setting up a Spring Boot project with Maven as your build tool.
  • Creating the Fat Jar: I introduced you to the spring-boot-maven-plugin, which is the secret sauce for creating a Fat Jar. When you executed the mvn clean package command, Maven cleared any previous builds, then compiled, tested, and packaged your project into a standalone, executable jar.
  • Running the Fat Jar: You saw how simple it is to run the application using the java -jar command. This confirmed that the Fat Jar is a self-contained package with all the necessary code and dependencies for your application.
  • Including and Excluding dependencies: You have also learned how to include or exclude dependencies from you fat jar Spring Boot application.

But don’t stop here – there’s more to explore and learn. I invite you to check out my other tutorials on creating RESTful Spring Boot applications. Keep coding and keep learning!