Spring Boot: the Web project is deployed to external tomcat deployment in the form of War package

Spring boot projects are usually packaged as jar s and can be run directly, which is relatively convenient. However, recently, the project needs to package the springboot project into a war and run it in a separate tomcat. There are still many things to pay attention to.

1. Inherit SpringBootServletInitializer

For external container deployment, you need to inherit SpringBootServletInitializer in the startup class and implement the configure method in application The sources method passes in the startup class.

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 WarDemoApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
        return application.sources(WarDemoApplication.class);
    }
 
    public static void main(String[] args) { 
        SpringApplication.run(WarDemoApplication.class, args);
    }
 
}
 

 2,pom.xml to modify tomcat related configuration

If you want to change the final packaging form to war, you also need to modify POM Modify the XML file. Because spring boot starter web contains an embedded tomcat container, deploying directly in an external container will conflict and report an error.

There are two ways to solve this problem, as follows

Method 1: remove Tomcat dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Here, you need to remove the dependency on embedded tomcat, so that the war package will not contain Tomcat related jar packages in the lib directory.

Another key point is that the scope in Tomcat embedded Jasper must be provided.

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

Because SpringBootServletInitializer needs to rely on javax Servlet, and there is this javax in tomcat embedded core under tomcat embedded Jasper If provided is not used for servlets, there will be a servlet API jar in the final war, which will conflict with tomcat itself.

Method 2: configure Tomcat to provided

Spring Boot starter Tomcat is configured by Spring Boot by default, that is, the embedded Tomcat of Spring Boot. Setting it to provided will exclude the package (dependency) during packaging, because the embedded Tomcat of Spring Boot does not need to be used to run in an independent Tomcat.
 

        <!--Deploy as war Enable [support at the same time] when package war and jar Start deployment]↓↓↓↓-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--Deploy as war Enable [support at the same time] when package war and jar Start deployment]↑↑↑↑-->

The advantage of this method is that the packaged war package is suitable for both Java jar command startup and deployment to an external container.

3. From jar to war

<packaging>war</packaging>

4. Problems needing attention

4.1 consistency between project name and package name

When using external Tomcat deployment access, application Properties (or application.yml) Port and server servlet. Context path will fail.

The port of tomcat and the project name under tomcat and webapps will be used for access. In order to prevent the problem that the project access resources cannot be loaded due to the application context, it is recommended that POM Add the < finalname > < / finalname > tag under the < build > < / build > tag in the XML file:

<build>
    <!-- Should and application.properties(or application.yml)in context-path bring into correspondence with -->
    <finalName>war Package name</finalName>    
</build>

At this time, the name of the printed package should be the same as application Properties

server.port=8081
server.servlet.context-path=/war-demo

Note spring boot 2 x. It is written as server servlet. context-path=

bring into correspondence with
 

<build>
    <finalName>war-demo</finalName>
</build>

4.3,Error assembling WAR: web.xml attribute is required
 Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war)

on project XXX: Error assembling WAR: web.xml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)

This tip is not that you lack dependencies, but that there is no web when packaging XML file, because there is no web.xml file under multiple modules of SpringCloud microservice XML file, which does not need to be added at this time. Add a line of code under the pom file as follows:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
     <version>3.0.0</version>
     <configuration>
         <failOnMissingWebXml>false</failOnMissingWebXml>
         <warName>${project.artifactId}</warName>
     </configuration>
</plugin>

There is no need to use the packaging of jar package at this time.

<!-- <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.1.1.RELEASE</version>
        <configuration>
             <fork>true</fork> If there is no such configuration, devtools Will not take effect
        </configuration>
        <executions>
            <execution>
               <goals>
                   <goal>repackage</goal>
               </goals>
            </execution>
        </executions>
     </plugin> -->

Keywords: Java Spring Boot Tomcat

Added by powlouk on Tue, 04 Jan 2022 02:10:06 +0200