无法在外部 Tomcat 7 上部署 Spring-引导 WAR 文件

Can't deploy Spring-Boot WAR file on External Tomcat 7

开发团队正在 Ubuntu 服务器上使用 Tomcat 7。我从服务器下载 Tomcat 并在本地部署,它工作正常。

现在,我开发了一个 spring-boot 模块,将其包装到 WAR 文件中,并希望将其部署在同一个 Tomcat 中。但是,catalina.bat run 无法启动我的 spring-boot 应用程序。原始应用程序(称为 ROOT)工作正常。

我的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>kz.iuth.platonus</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/e-iceblue/spire.doc.free -->
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.doc.free</artifactId>
            <version>3.9.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.json/json -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20211205</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.0.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.11</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

我的 application.properties 文件:

spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost/nitro?characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

spring.thymeleaf.cache=false

spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB

主应用程序class:

package kz.iuth.platonus.demo;

import kz.iuth.platonus.demo.entities.Roles;
import kz.iuth.platonus.demo.services.RolesService;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) {
        return applicationBuilder.sources(DemoApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

控制器:

@RestController
public class MainController {
...
    @GetMapping("/")
    public String test() {
        return "test";
    }

catalina.bat run 错误:

INFO: Deploying web application archive [C:\Program Files\tomcat7\webapps\demo-0.0.1-SNAPSHOT.war]
Feb 24, 2022 2:55:39 AM org.apache.catalina.core.StandardContext postWorkDirectory
WARNING: Failed to create work directory [C:\Program Files\tomcat7\work\Catalina\localhost\demo-0.0.1-SNAPSHOT] for context [/demo-0.0.1-SNAPSHOT]
Feb 24, 2022 2:55:39 AM org.apache.catalina.loader.WebappClassLoaderBase validateJarFile
INFO: validateJarFile(C:\Program Files\tomcat7\webapps\demo-0.0.1-SNAPSHOT\WEB-INF\lib\javax.servlet-api-3.1.0.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
Feb 24, 2022 2:55:43 AM org.apache.catalina.startup.TldConfig execute
INFO: 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.

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.1)

2022-02-24 02:55:44.350  INFO 33832 --- [ost-startStop-1] kz.iuth.platonus.demo.DemoApplication    : Starting DemoApplication using Java 1.8.0_311 on DESKTOP-961M2T3 with PID 33832 (C:\Program Files\tomcat7\webapps\demo-0.0.1-SNAPSHOT\WEB-INF\classes started by BIG SEXY BOSS 3090 in C:\Program Files\tomcat7\webapps)
2022-02-24 02:55:44.356  INFO 33832 --- [ost-startStop-1] kz.iuth.platonus.demo.DemoApplication    : No active profile set, falling back to default profiles: default
2022-02-24 02:55:45.012  INFO 33832 --- [ost-startStop-1] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-02-24 02:55:45.109  INFO 33832 --- [ost-startStop-1] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 87 ms. Found 11 JPA repository interfaces.
2022-02-24 02:55:45.481  INFO 33832 --- [ost-startStop-1] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1076 ms
2022-02-24 02:55:45.678  WARN 33832 --- [ost-startStop-1] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionIdListener
2022-02-24 02:55:45.690  INFO 33832 --- [ost-startStop-1] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-02-24 02:55:45.716 ERROR 33832 --- [ost-startStop-1] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionIdListener
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175) [spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155) [spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97) [spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174) [spring-web-5.3.13.jar:5.3.13]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5709) [catalina.jar:7.0.99]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:7.0.99]
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1016) [catalina.jar:7.0.99]
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:992) [catalina.jar:7.0.99]
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:639) [catalina.jar:7.0.99]
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127) [catalina.jar:7.0.99]
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2020) [catalina.jar:7.0.99]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_311]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_311]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_311]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_311]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_311]
Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionIdListener
        at org.springframework.boot.web.servlet.ServletListenerRegistrationBean.<clinit>(ServletListenerRegistrationBean.java:68) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:156) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:87) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:191) ~[spring-boot-2.6.1.jar:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.6.1.jar:2.6.1]
        ... 21 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpSessionIdListener
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1951) ~[catalina.jar:7.0.99]
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1794) ~[catalina.jar:7.0.99]
        ... 28 common frames omitted

Feb 24, 2022 2:55:45 AM org.apache.catalina.core.ContainerBase addChildInternal
SEVERE: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/demo-0.0.1-SNAPSHOT]]
        at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1016)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:992)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:639)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2020)
        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: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionIdListener
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5709)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        ... 10 more
Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionIdListener
        at org.springframework.boot.web.servlet.ServletListenerRegistrationBean.<clinit>(ServletListenerRegistrationBean.java:68)
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:156)
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:87)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:191)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
        ... 21 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpSessionIdListener
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1951)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1794)
        ... 28 more

Feb 24, 2022 2:55:45 AM org.apache.catalina.startup.HostConfig deployWAR
SEVERE: Error deploying web application archive [C:\Program Files\tomcat7\webapps\demo-0.0.1-SNAPSHOT.war]
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/demo-0.0.1-SNAPSHOT]]
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1020)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:992)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:639)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2020)
        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)

Feb 24, 2022 2:55:45 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive [C:\Program Files\tomcat7\webapps\demo-0.0.1-SNAPSHOT.war] has finished in [6,000] ms

当我 http://localhost:8080/demo-0.0.1-SNAPSHOT 时,我收到 404 错误。

tomcat 配置中可能存在一些问题,因为我使用的是从服务器下载的 tomcat 目录,而不是从 Internet 下载的默认(干净)目录,但我'我不确定在哪里查看以及更改什么。

注意:我知道默认情况下 catalina.bat runlocalhost:8080 之后,Tomcat 的默认欢迎页面需要弹出,但就我而言,我得到了欢迎our application 页(ROOT)。可能是这样吧,我不知道。

部署到 Tomcat 8 或更高版本

您的错误提示找不到接口 HttpSessionIdListener

查看该接口的 Javadoc 告诉我们它是在 Servlet 3.1 规范中添加的。

现在查看 Tomcat 站点上的 Which version? 页面。在那里我们看到 Tomcat 7 支持 Servlet 3.0。对于 Servlet 3.1,您需要 Tomcat 8 或更高版本。

请注意 Tomcat 8.0.x 已被 Tomcat 8.5.x.

取代