How to Deploy a Spring Boot WAR to Tomcat

tomcat-springboot.png

Overview

Spring Boot includes an embedded Tomcat server which makes it easy to run web applications.  The application code, libraries, and embedded Tomcat server are packaged in an executable JAR that can be run from the command-line without any additional server setup.

However, the embedded Tomcat server is not suitable for every environment.   There may be a standalone Tomcat server that should be used instead.

In this article, we'll cover how to deploy a Spring boot application WAR to an standalone Tomcat instance.


Steps

  1. Disable the embedded Tomcat in Spring Boot
  2. Change the package type to WAR
  3. Extend SpringBootServletInitializer in main application class
  4. Upload the WAR file to Tomcat webapps directory

Disable the embedded Tomcat in Spring Boot

First, we need to tell Spring Boot to not use its embedded Tomcat as the servlet container for the application.

Maven

Add the following dependency to pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
</dependency>

Gradle

Add the following to the dependencies block in build.gradle:

providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'

Change the package type to WAR

Now, let's change the package type from JAR to WAR

Maven

Change the packaging property in pom.xml:

<packaging>war</packaging>

Gradle

apply plugin: "war"

Extend SpringBootServletInitializer in main Application class

Spring Boot applications have a class containing a main() method responsible for launching the application.  We need to modify this class to extend the SpringBootServletInitializer and override the configure() method.

This makes our application compatible with running inside a separate servlet container.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(Application.class);
  }

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

Build the WAR file

Maven

mvn clean package

Gradle

gradle war

Upload the WAR file to Tomcat

This step assumes that the Tomcat instance configured for autodeploy.   This is enabled by default.

Upload the generated WAR file to the Tomcat server in the webapps directory.

Tail the contents of logs/catalina.out to verify that deployment completed with no errors:

12-May-2018 19:59:22.501 INFO [localhost-startStop-3] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/apache-tomcat-8.5.15/webapps/demo-2.0-0.0.1-SNAPSHOT.war]
.....
12-May-2018 19:59:28.876 INFO [localhost-startStop-3] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/apache-tomcat-8.5.15/webapps/demo-2.0-0.0.1-SNAPSHOT.war] has finished in [6,378] ms