How to deploy Spring Boot applications on Tomcat (as WAR)

By default, Spring-Boot applications are packaged as JAR files and they have an embedded container that hosts them. The embedded container allows developers to not have any web server installed in order to run their apps. This is pretty cool and brings many benefits for developers like easier deployment and management.

However, customers usually have their own IT landscape and might want you to deliver them a classic WAR file. Their dev ops team can then take that WAR file and deploy it on a stand-alone Tomcat server. In this article, we’ll see how easy it is to deploy Spring Boot applications on Tomcat, as WAR files. All you need is a couple of minutes.

1) Modify the pom.xml file

Change the packaging from jar to war. Thus, when building the application, the final artifact will now be a WAR file.

...
<packaging>war</packaging>
...

2) Exclude the embedded container dependency from the final artifact

This is required because the embedded container can conflict with the Tomcat server. Thus, it is necessary to exclude it from the WAR artifact. You can achieve this by marking the dependency as ‘provided’ in the pom.xml file.

...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
...

A provided dependency is not present in the final artifact (JAR or WAR). Instead, another component (JDK or container) shall provide it at runtime. What this means is that:
– You can safely deploy the WAR on a dedicated server, without fear of conflicts
– The WAR remains executable. You can still run your app using the java –jar command, just like you do with standard Spring-Boot applications. When you do this, the dependency shall be provided at runtime for you.

You retain full flexibility regarding the deployment. The generated WAR file can be executed using java –jar command or it can be deployed in a stand-alone container. It is up to you.

3) Modify the @SpringBootApplication class.

You need to extend SpringBootServletInitializer and override the ‘configure’ method like shown below.

@SpringBootApplication
public class BookingDemoApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(BookingDemoApplication.class, args);
    }

    // Override the configure method from the SpringBootServletInitializer class
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(BookingDemoApplication.class);
    }
}

4) Small issue on IntelliJ (java.lang.ClassNotFoundException: javax.servlet.ServletContext)

Once you’ve done all the things listed above, you are set to go. You can deploy your application on Tomcat or you can execute it using java –jar. But, you might get an error in IntelliJ if you try to start the application using the standard SpringBoot running configuration. There is nothing wrong with the application, but we need to change the runtime configuration in IntelliJ. You have to use JAR Application configuration and to execute the package Maven goal before each execution. This will allow you to start and debug this application in IntelliJ.
Spring Boot JAR running config

5) More resources

I have also posted a video tutorial on YouTube that presents how to transform a standard Spring-Boot application into a WAR web application that can be deployed on Tomcat.
If you like source-code, then you can check out a complete example on GitHub.