Newsletter

How to Deploy Spring Boot Applications on External Tomcat Server

Spring-Boot-Tutorials » on Apr 28, 2018 { 14 Comments } By Sivateja

So far, in previous examples we used to deploy and run the applications using embedded tomcat server provided by the spring boot. Generally in the real-time projects we wont use inbuilt servers provided by the frameworks because of many reasons like security, maintenance and control. So in this article I will show you how can we deploy the spring boot applications on external servers (in this tutorial I am going to consider the external server as Tomcat).

Just do these changes to your spring boot application which you want to deploy it on to external tomcat server.

  • pom.xml, add dependency and packaging to war
  • Extend your main class with SpringBootServletInitializer and override its configure method
  • Generate WAR and deploy into the external server

If want you can change the context path also in the application.properties. (Optional)

pom.xml

<!-- to export as WAR -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>

<!-- packaging to WAR -->
<packaging>war</packaging>

Final pom.xml

<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>
    <groupId>com.java4s</groupId>
    <artifactId>SpringBootAppInExternalTomcat</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <!-- packaging to WAR -->
    <packaging>war</packaging>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Instruct spring boot not to use the inbuilt Tomcat server -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
    </properties>
</project>

Extend main Class with SpringBootServletInitializer

package com.java4s.app;

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 SpringBootApp extends SpringBootServletInitializer {

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

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

application.properties

server.contextPath=/springbootapp

SpringJava4sController.java

package com.java4s.app.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpringJava4sController {

 @RequestMapping("/java4s-spring-boot-ex-tomcat")
 public String customerInformation() {
      return "Hey, I am from external tomcat";
 }

}

Generate a WAR file

Right click on pom.xml -> Run as -> Maven install, this will generate a WAR file in your target folder.  Just copy that WAR file into your tomcat’s webapps folder and start the server ( or ) you can deploy and test from your IDE (eclipse/sts) by importing that WAR into your work space and run that in the external tomcat [I tried importing into eclipse].

Output


Note:
If you observe the context path in the URL, its showing SpringBootAppInExternalTomcat-0.0.1-SNAPSHOT. Its not taking the context path we have given in the application.properties, rather its considering the context path as Artifact Id + Version from pom.xml. So if you want required context path, the only possibility is change pom.xml accordingly (if you know other ways please comment).

You can download the application and generate the WAR file with the above step and verify.

​​

You Might Also Like

  ::. About the Author .::

Java4s_Author
Sivateja Kandula - Java/J2EE Full Stack Developer
Founder of Java4s - Get It Yourself, A popular Java/J2EE Programming Blog, Love Java and UI frameworks.
You can sign-up for the Email Newsletter for your daily dose of Java tutorials.

Comments

14 Responses to “How to Deploy Spring Boot Applications on External Tomcat Server”
  1. Ajith Alex says:

    My students are referring to this tutorials. Good article dude. 🙂

  2. Hussain says:

    Nice explanation bro.

  3. vineet Kumar says:

    I am not clear with why it is not taking context path from application.properties . It will not read context path only or not read any given property from application.properties file at all.

  4. satish says:

    Hi Siva, Has anyone used Spring Boot app with native Tomcat in production scenarios?

  5. Gayathri says:

    Hi Sir,

    I have used weblogic as external server and the war got deployed successfully with few changes, can you share me that how is the URL got framed, what is the URL to hit like http://host:port/artifact-version/controller name

  6. SATYANARAYANA K says:

    Context path can be set in following file : src/main/webapp/META-INF/context.xml
    <Context path="/mybootapp/" />

  7. Ravi says:

    Hi Sivateja, As you asked for contextPath , can try below : –

    server.context-path=/springbootapp

  8. Wang says:

    I am getting the error from the Tomcat log.

    01-Oct-2018 14:29:57.442 INFO [http-nio-8080-exec-43] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    01-Oct-2018 14:30:11.851 SEVERE [http-nio-8080-exec-43] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
    01-Oct-2018 14:30:11.852 SEVERE [http-nio-8080-exec-43] org.apache.catalina.core.StandardContext.startInternal Context [/test] startup failed due to previous errors
    01-Oct-2018 14:30:11.889 WARNING [http-nio-8080-exec-43] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [test] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
    01-Oct-2018 14:30:11.889 WARNING [http-nio-8080-exec-43] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [test] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    java.base@10.0.2/java.lang.Object.wait(Native Method)
    java.base@10.0.2/java.lang.ref.ReferenceQueue.remove(Unknown Source)
    com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:64)
    java.base@10.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.base@10.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.base@10.0.2/java.lang.Thread.run(Unknown Source)
    01-Oct-2018 14:30:12.932 INFO [Abandoned connection cleanup thread] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1329)
    at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1006)
    at com.mysql.jdbc.AbandonedConnectionCleanupThread.checkContextClassLoaders(AbandonedConnectionCleanupThread.java:90)
    at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:63)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

  9. Binh Thanh Nguyen says:

    Thanks, nice post

  10. Jang2212 says:

    On delopying the war file in tomcat getting the below error :

    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/SpringBootAppInExternalTomcat]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.IllegalArgumentException: More than one fragment with the name [spring_web] was found. This is not legal with relative ordering. See section 8.2.2 2c of the Servlet specification for details. Consider using absolute ordering.
    at org.apache.tomcat.util.descriptor.web.WebXml.orderWebFragments(WebXml.java:2200)
    at org.apache.tomcat.util.descriptor.web.WebXml.orderWebFragments(WebXml.java:2159)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1124)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:769)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:299)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5181)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    … 10 more

    Mar 19, 2019 10:07:20 AM org.apache.catalina.startup.HostConfig deployWAR
    SEVERE: Error deploying web application archive [C:\Software\apache-tomcat-8.5.38-windows-x64\apache-tomcat-8.5.38\webapps\SpringBootAppInExternalTomcat.war]
    java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/SpringBootAppInExternalTomcat]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:758)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

  11. Raj says:

    application.properties file is not loading while start the tomcat server. throwing error unsatisfieddependencyexception error creating bean with name "datasource". actually i have specified my DB credentials in application.properties file.

  12. Dinesh says:

    Hi Sivateja,

    No need of application.properties.
    Use <finalName>springbootapp</finalName> in <build> tag in your pom.xml.
    It will resolve your issue.

    Regards,
    Dinesh

Name*
Mail*
Website



By posting your answer, you agree to our comments policy.
Most Recent Posts from Top Categories
Spring Boot Hibernate Spring
Contact | About Us | Privacy Policy | Advertise With Us

© 2010 - 2024 Java4s - Get It Yourself.
The content is copyrighted to Sivateja Kandula and may not be reproduced on other websites.