1. Introduction

One of the more heart-warming developments of recent years has been an ongoing simplification of how web applications are deployed.

Skipping all the boring intermediate historical steps, we arrive at today – when we can dispense with not only cumbersome servlets and XML boilerplate, but mostly the servers themselves.

This article will concentrate on creating a “fat jar” out of a Spring Boot application – basically to create a single artifact that is easy to deploy and run.

Boot provides capabilities for container-less deployments right out of the box: all we need to do is to add a couple of configurations in the pom.xml:

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

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

2. Build and Run

With this configuration, we can now simply build the project with the standard mvn clean install – nothing unusual here.

And we run it with the following command: java -jar – very simple and intuitive.

Proper process management is beyond the scope of this article, but one simple way to keep the process running even when we logoff the server is to use the nohup command: nohup java -jar .

Stopping spring-boot projects is also no different than stopping a regular process, whether we simply cntrl+c or kill .

3. Fat Jar / Fat War

Behind the scenes, spring-boot packages all the project dependencies inside the final artifact along side project classes (hence the “fat” jar). An embedded Tomcat server is also built-in.

And thus, the resulting artifact is completely self-contained, easy to deploy using standard Unix tools (scp, sftp…etc) and can be run on any server with a JVM.

By default, Boot creates a jar file – but if we change the packaging property in pom.xml to war, Maven will instead naturally build a war.

This will of course be both executable as stand-alone, and deployed to a web container.

4. Further Config

Most of the time no additional configuration is needed, everything “just works”, but in some specific cases, we may need to tell spring-boot explicitly what the main class is. One way to do it would be to add a property:

<properties>
    <start-class>org.baeldung.boot.Application</start-class>
</properties>

In case we’re not inheriting spring-boot-starter-parent we’ll need to do it in the Maven plugin:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.4.0</version>
    <configuration>
        <mainClass>org.baeldung.boot.Application</mainClass>
        <layout>ZIP</layout>
    </configuration>
</plugin>

Another thing we might need to do in some rare cases is to instruct Maven to unpack some dependencies:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <requiresUnpack>
            <dependency>
                <groupId>org.jruby</groupId>
                <artifactId>jruby-complete</artifactId>
            </dependency>
        </requiresUnpack>
    </configuration>
</plugin>

5. Conclusion

In this article, we looked at server-less deployment using “fat” jars built by spring-boot.

As always, the code in this writeup is all available over on Github.