Deploy Spring Boot to Tomcat

49,915

Solution 1

The chapter Packaging executable jar and war files in the Spring Boot reference documentation states:

To build a war file that is both executable and deployable into an external container you need to mark the embedded container dependencies as “provided”, e.g:

<?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">
    <!-- ... -->
    <packaging>war</packaging>
    <!-- ... -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- ... -->
    </dependencies>
</project>

Solution 2

Below code worked fine for tomcat8 deployment without tomcat dependency.

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan
public class ManufacturingRegionApplication extends SpringBootServletInitializer {

public static void main(String[] args) {
    new SpringApplicationBuilder(ManufacturingRegionApplication.class).application().run(args);
}

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

private static Class<ManufacturingRegionApplication> application = ManufacturingRegionApplication.class;

}

Below dependency is not required.

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

 @RestController
 @RequestMapping(value = "/manufacturing-region-service")
 public class ManufacturingRegionService {

@Resource
private ManufacturingRegionDao manufacturingRegionDao;

@ResponseBody
@Transactional(readOnly = true)
@RequestMapping(value = "/region-codes/{abbr}", method = GET, produces = "application/json")

http://localhost:8080/manufacturing-region-api/manufacturing-region-service/region-codes/ABBRVALUE

Share:
49,915
philthomas26
Author by

philthomas26

Updated on October 28, 2020

Comments

  • philthomas26
    philthomas26 over 3 years

    So I am new to Spring - so I thought I would try Spring Boot

    I am using a Maven to build - I set up a view requests, when I run it as "App" looks like it starts tomcat up itself and i have a service at default 8080 port, so when I call localhost:8080/service it's all good.

    However when i try to package it up as a WAR to deploy to a server it doesn't work

    So i thought i would go back to basics and deploy it onto my tomcat server locally and see what happens

    So first off nothing happened - 404 - did a bit of googling at found out i need to include a web entry point like this - here's my main class

    @ComponentScan
    @EnableAutoConfiguration
    public class App extends SpringBootServletInitializer
    {
    
        public static void main( String[] args )    {
            SpringApplication.run(App.class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(appClass);
        }
    
        private static Class<App> appClass = App.class;
    }
    

    so it looked like it worked, in the console i could see the red catalina startup text, then i saw the Spring boot start up (which i wasn't seeing before)

    however when i try and call the service localhost:8080/service i still get a 404

    when i run it as "App" it works a treat

    is there something obvious i need to be doing ? to create the war i just

    1. changed the pom xml package type to war
    2. included the override in the code snippet above
    3. exported as a war

    i have unzipped the WAR and it looked fine - there is a WEB-INF and a set of dependencies, etc.

    any help would be good - as anyone had similar problems when deploying spring boot apps as a WAR?

    ***UPDATE****

    Now i can get my war to deploy correctly on my local Tomcat 7 server - but when i try and deploy to an externally hosted Tomcat container i get

    at       org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5262)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 15 more
    Jul 14, 2014 1:49:01 PM org.apache.catalina.startup.HostConfig deployDirectory
    SEVERE: Error deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/cookpot
    java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/cookpot]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:898)
    at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:130)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:153)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:142)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:869)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1095)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1617)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
    Jul 14, 2014 1:49:01 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/examples
    Jul 14, 2014 1:49:01 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/host-manager
    Jul 14, 2014 1:49:01 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/CookPot
    Jul 14, 2014 1:49:02 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
    INFO: validateJarFile(/usr/local/shared/tomcat/thecookpot/webapps/CookPot/WEB-INF/lib/tomcat-embed-core-7.0.52.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
    Jul 14, 2014 1:49:02 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
    INFO: validateJarFile(/usr/local/shared/tomcat/thecookpot/webapps/CookPot/WEB-INF/lib/tomcat-embed-el-7.0.52.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
    Jul 14, 2014 1:49:06 PM org.apache.catalina.core.ContainerBase addChildInternal
    SEVERE: ContainerBase.addChild: start:
    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/CookPot]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895)
    at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:130)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:153)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:142)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:869)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1095)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1617)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
    Caused by: java.security.AccessControlException: access denied (java.util.PropertyPermission java.awt.headless write)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
    at java.security.AccessController.checkPermission(AccessController.java:546)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at java.lang.System.setProperty(System.java:727)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:263)
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
    at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
    at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5262)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 15 more
    Jul 14, 2014 1:49:06 PM org.apache.catalina.startup.HostConfig deployDirectory
    SEVERE: Error deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/CookPot
    java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/CookPot]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:898)
    at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:130)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:153)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:142)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:869)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1095)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1617)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
    Jul 14, 2014 1:49:06 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/ROOT
    Jul 14, 2014 1:49:06 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/manager
    Jul 14, 2014 1:49:06 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/docs
    Jul 14, 2014 1:49:06 PM org.apache.catalina.startup.HostConfig deployDirectory
    INFO: Deploying web application directory /usr/local/shared/tomcat/thecookpot/webapps/Cookpot
    Jul 14, 2014 1:49:06 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
    INFO: validateJarFile(/usr/local/shared/tomcat/thecookpot/webapps/Cookpot/WEB-INF/lib/tomcat-embed-core-7.0.52.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
    Jul 14, 2014 1:49:06 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
    INFO: validateJarFile(/usr/local/shared/tomcat/thecookpot/webapps/Cookpot/WEB-INF/lib/tomcat-embed-el-7.0.52.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
    Jul 14, 2014 1:49:09 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-bio-6350"]
    Jul 14, 2014 1:49:09 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-bio-4350"]
    Jul 14, 2014 1:49:09 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 17529 ms
    
  • Engineer2021
    Engineer2021 almost 10 years
    It would help if you would post a relevant example on how to do this properly
  • aaiezza
    aaiezza about 9 years
    @staticx that can be found right on Spring's site: convert Spring Boot JAR to WAR. But mcoolive actually does answer this question better than James' in my opinion, consider no one has addressed that the question is strange. The whole point of Spring Boot is to run a simple jar file. You only produce a war file if you are using a java servlet container like tomcat for instance. For better info on that check this out: spring.io inside and out
  • Stefano Bragaglia
    Stefano Bragaglia almost 9 years
    This comment doesn't answer to the question.
  • cbmeeks
    cbmeeks over 8 years
    Do comments normally answer questions?
  • P Marecki
    P Marecki over 8 years
    This "answer" only provides author's opinion on wheather he finds the aims of the OP reasonable or not.
  • P Marecki
    P Marecki over 8 years
    I believe I had to mvn clean before mvn package finally produced a .war deployable to tomcat, while applying this solution (it finally worked).
  • P Marecki
    P Marecki over 8 years
    Summary of steps to ".war-ize" spring-boot app: (1) <packaging>war</packaging>, and the above dependency with "provided" in pom.xml, (2) modifying Application.java by extends SpringBootServletInitializer with the @Override as in the question. Produces .war runnable via java -jar and deployable to tomcat 7.0.59 and jetty 9.3.6 using spring-boot 1.3.1.
  • albfan
    albfan over 8 years
    It's important to remark that spring-boot-maven-plugin build plugin should call goal repackage See doc.