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.
Spring Boot provides capabilities for container-less deployments right out of the box: all you need to do is to add a couple of configurations in your pom.xml:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.1.RELEASE</version> </dependency> </dependencies> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.0.1.RELEASE</version> </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 <artifact-name> – 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 you log off the server is to use the nohup command: nohup java -jar <artifact-name>.
Stopping spring-boot projects is also no different than stopping a regular process, whether you simply cntrl+c or kill <pid>.
3. Fat Jar / Fat War
Behind the scenes, spring-boot packages all the project dependencies inside the final artifact alongside 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, Spring 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, you might 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>com.dailycodebuffer.example.SpringBootApplication</start-class> </properties>
In case you are not inheriting spring-boot-starter-parent you’ll need to do it in the maven plugin:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.0.1.RELEASE</version> <configuration> <mainClass>com.dailycodebuffer.example.SpringBootApplication</mainClass> <layout>ZIP</layout> </configuration> </plugin>
Another thing you 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>
In this article, we looked at server-less deployment using “fat/Uber/Executable” jars built by spring-boot.