Spring Boot – Deploy WAR file to Tomcat

In this article, we will show you how to deploy a Spring Boot WAR file to the Tomcat servlet container.

For Spring Boot WAR deployment, you need to do three steps:

  1. Extends SpringBootServletInitializer
  2. Marked the embedded servlet container as provided.
  3. Update packaging to war

Tested

  1. Spring Boot 1.4.2.RELEASE
  2. Tomcat 8.5.9
  3. Maven 3
Note
In Spring Boot, the final executable JAR file with embedded server solution may not suitable in all production environments, especially the deployment team (a team with good knowledge of server optimization and monitoring skills, but lack of, the development experience), they want full control of the server, and they don’t touch code.

1. Extends SpringBootServletInitializer

Make the existing @SpringBootApplication class extends SpringBootServletInitializer

1.1 Classic Spring Boot JAR deployment. (Update this file to support WAR deployment)

SpringBootWebApplication.java

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootWebApplication {

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

}

1.2 Spring Boot WAR deployment.

SpringBootWebApplication.java

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

@SpringBootApplication
public class SpringBootWebApplication extends SpringBootServletInitializer {

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

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

}

/*@SpringBootApplication
public class SpringBootWebApplication {

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

}*/

If you create a extra SpringBootWebApplication class for deployment, make sure tell Spring Boot which main class to start :

pom.xml

  <properties>
        <start-class>com.mkyong.NewSpringBootWebApplicationForWAR</start-class>
  </properties>

Read this – Spring Boot – Which main class to start

2. Marked the embedded servlet container as provided

pom.xml

<dependencies>

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

	<!-- marked the embedded servlet container as provided -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
		<scope>provided</scope>
	</dependency>

</dependencies>

3. Update packaging to war

pom.xml

  <packaging>war</packaging>

Done, mvn package and copy the $project/target/xxx.war to Tomcat for deployment.

4. Full example – Spring Boot WAR + Tomcat Deployment

4.1 Take this Spring Boot Thymeleaf example, update it and deploy to Tomcat manually.

4.2 Update the existing SpringBootWebApplication and make it extends the SpringBootServletInitializer

pom.xml

package com.mkyong;

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

@SpringBootApplication
public class SpringBootWebApplication extends SpringBootServletInitializer {

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

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

}

4.3 Update the packaging to war and mark the spring-boot-starter-tomcat as provided.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-boot-web-thymeleaf</artifactId>
    <packaging>war</packaging>
    <name>Spring Boot Web Thymeleaf Example</name>
    <description>Spring Boot Web Thymeleaf Example</description>
    <url>https://www.mkyong.com</url>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

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

        <!-- marked the embedded servlet container as provided -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- hot swapping, disable cache for template, enable live reload -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- Optional, for bootstrap -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <!-- Package as an executable jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4.4 This is optional, update the contextPath to /mkyong for demonstration later. Done. Ready for WAR deployment.

application.properties

welcome.message: Hello Mkyong

server.contextPath=/mkyong

4.5 Get Tomcat and Deploy WAR file.

Mac OS X : Terminal


# Get Tomcat 8.5.9
spring-boot-project$ curl -O  http://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.9/bin/apache-tomcat-8.5.9.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 9112k  100 9112k    0     0   799k      0  0:00:11  0:00:11 --:--:-- 1348k

# Extract it
$ tar -xvzf apache-tomcat-8.5.9.tar.gz 

# Maven clean and package everything into a WAR file.
$ mvn clean package

# Copy WAR to Tomcat/webapp, renamed to mkyong.war
# By default, Tomcat take the war file name as the context path
$ cp target/spring-boot-web-thymeleaf-1.0.war apache-tomcat-8.5.9/webapps/mkyong.war

# Start Tomcat
$ ./apache-tomcat-8.5.9/bin/startup.sh 
Using CATALINA_BASE:   /Users/mkyong/projects/spring-boot-web-thymeleaf/apache-tomcat-8.5.9
Using CATALINA_HOME:   /Users/mkyong/projects/spring-boot-web-thymeleaf/apache-tomcat-8.5.9
Using CATALINA_TMPDIR: /Users/mkyong/projects/spring-boot-web-thymeleaf/apache-tomcat-8.5.9/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home
Using CLASSPATH:       /Users/mkyong/projects/spring-boot-web-thymeleaf/apache-tomcat-8.5.9/bin/bootstrap.jar:
/Users/mkyong/projects/spring-boot-web-thymeleaf/apache-tomcat-8.5.9/bin/tomcat-juli.jar
Tomcat started.

4.6 Access http://localhost:8080/mkyong/

spring-boot-tomcat-deployment

4.7 Done. Shut down Tomcat.

Mac OS X : Terminal

$ ./apache-tomcat-8.5.9/bin/shutdown.sh 

Download Source Code

Download – spring-boot-war-tomcat.zip (13 KB)

References

  1. Spring Boot – Traditional deployment
  2. Spring Boot Hello World Example – Thymeleaf
  3. How to Install Apache Tomcat 8 On Debian

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
Adolf Mrls
Guest
Adolf Mrls

Hi Mkyong, great tutorial
in the case to need a “upload-dir” where?
(i put it in the root and dont work x( ) Help pls!

Mohammed Qurashi
Guest
Mohammed Qurashi

Awesome tutorial, I had it working for my spring-boot app on tomcat 8

nonsaprei
Guest
nonsaprei

I just wanted to add that specifying a server.contextPath in the application.properties is pointless, because Tomcat won’t let you use that.

ronald haring
Guest
ronald haring

only works on servlet3+ containers i think, tomcat 7 does nothing

Gabriel Andrade
Guest
Gabriel Andrade

Im using spring boot with JSF and i am able to start the server just fine, but after a while(around 1 or 2 days), the server stops and cant startup again, giving me the error:
2018-02-18 10:30:08.018 INFO 7052 — [localhost-startStop-2] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2e601386: startup date [Thu Feb 15 13:20:57 UTC 2018]; root of context hierarchy
2018-02-18 10:30:08.033 INFO 7052 — [localhost-startStop-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown

Chhorn Elit
Guest
Chhorn Elit

I build your war to deploy, but cannot. Then I realize the pom.xml specify java 8.0. However, tomcat server were running on java 7.0. Thanks though.

Anthony
Guest
Anthony

Thanks for the tutorial!
Is there a more seamless way to continue deployment to the application. (In case I made a small change to a template for example). I would have to re-upload the whole war file to tomcat.

Rohit Basu
Guest
Rohit Basu

I tried my own and i post the issue in
https://stackoverflow.com/questions/47294386/issues-in-spring-boot-war-file-deployment-in-tomcat-server
I am getting error:
“Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Nov 16 18:03:35 IST 2017
There was an unexpected error (type=Not Found, status=404).
No message available”

Please check if you can help.

Cuong Bui Quang
Guest
Cuong Bui Quang

I follow your tutorial and my spring boot application runs twice when I deploy war to tomcat. I also solve this by remove Spring Boot Application from extending SpringBootServletInitializer, my Spring Boot version is 1.5.7.RELEASE

Shahid Akhtar
Guest
Shahid Akhtar

Hi Mkyong,
Would you please let me know how to set contextPath for spring boot application if deployed as a war on
standalone tomcat?

Regards,
Shahid Akhtar.

Pavithra
Guest
Pavithra

This tutor is very simple!! Thanks

phuctran
Guest
phuctran

to run your example, need to add “server.error.whitelabel.enabled=false” to application.properity

webdev
Guest
webdev

how to run this application

Amit
Guest
Amit

hi Mkyong,
I installed your example.
It seems server.contextPath is not recognized by external tomcat8.

Do you have any suggestions on how to set context path of a spring boot(1.5) application in external tomcat8?

Regards
Amit

Hetarth Shah
Guest
Hetarth Shah
Shahid Akhtar
Guest
Shahid Akhtar

Hi Shah,
Given link states about contextPath change will work for embedded tomcat. It does not work for
standalone containers. Would you please let me know how contextPath can be set for standalone
containers?

Thanks
Shahid Akhtar

Mohammed Amen
Guest
Mohammed Amen

By the way why do you need to deploy anything in stand alone container? You dont you use the embedded one …it is quite easy to use with very less work to do. If you are using eclipse as ide you can add tomcat maven compiler plugin in pom.xml along with the spring-boot-starter-tomcat. It is a perfect combination u only need to run the SpringBootWebApplication java class and then maven clean and install which will automatically add the war to the tomcat without unnecessary overhead and u can then load the page.

Shahid Akhtar
Guest
Shahid Akhtar

it does not work for standalone container

Salil Kumar
Guest
Salil Kumar

Hi Amit ,

To run this application , you need to add the below in application.properties.
server.port=8080
server.error.whitelabel.enabled=false.

Then run the below command :

C:……….> mvn spring-boot:run

Then open any browser and run :

http://localhost:8080/mkyong/

Dido
Guest
Dido

Every request I make returns 401. I use JWT authentication. Anyone with the same problem?

Khamphai
Guest
Khamphai

how to deploy spring boot war file to glassfish4.1 server ?

Joel Rives
Guest
Joel Rives
I find the tutorial very simple and straight forward. I downloaded the code, built it and deployed to Tomcat. It works. I am now trying to apply this to my project with no luck yet. Here is the pertinent part of my project hierarchy: config SpringBootWebApplication controller HelloController The SpringBootWebApplication is exactly as in your tutorial The HelloController is my version of your WelcomeController. I looks like this: @Controller public class HelloController { @RequestMapping(“/”) public String index() { return “Greetings from Spring Boot!”; } } This does not work. The war deploys just fine but attempts to access it fail.… Read more »
Carol
Guest
Carol

Thank you!