Spring Boot 3.1.6升级部署失败:求兼容Java/Tomcat版本及解决方案
问题描述
- 在Docker环境中运行
Tomcat:10.1-jdk17-corretto镜像,搭配Spring Boot 3.0.5时部署运行完全正常。 - 将Spring Boot版本升级至3.1.6后,WAR包部署到Tomcat时出现启动失败问题。
- 推测原因可能是Spring Boot 3.1.6与当前Tomcat版本存在兼容性差异,且Docker Hub暂未提供更新版本的Tomcat JDK17 Corretto官方镜像。
Spring Boot 3.1.x 兼容版本说明
- Java版本:Spring Boot 3.1.x支持Java 17、19、20(Java 17为LTS版本,官方推荐),你的Java 17版本符合要求,可排除Java版本不兼容问题。
- Tomcat版本:Spring Boot 3.1.x默认集成的Tomcat版本为10.1.16+,你当前使用的
Tomcat:10.1-jdk17-corretto大概率是10.1系列的较早版本,API或配置上的差异是导致部署失败的核心原因。
解决办法
方案1:自定义构建兼容的Tomcat Corretto镜像
手动构建新版Tomcat+Corretto 17镜像,步骤如下:
- 创建
Dockerfile:
FROM amazoncorretto:17-alpine ENV CATALINA_HOME /usr/local/tomcat ENV PATH $CATALINA_HOME/bin:$PATH RUN mkdir -p "$CATALINA_HOME" WORKDIR $CATALINA_HOME # 下载解压Tomcat 10.1.18(可替换为10.1.16+的任意稳定版本) RUN wget -O tomcat.tar.gz https://archive.apache.org/dist/tomcat/tomcat-10/v10.1.18/bin/apache-tomcat-10.1.18.tar.gz \ && tar -xvf tomcat.tar.gz --strip-components=1 \ && rm tomcat.tar.gz \ && rm -rf webapps/examples webapps/docs EXPOSE 8080 CMD ["catalina.sh", "run"]
- 构建镜像:
docker build -t tomcat:10.1.18-jdk17-corretto .
- 使用该镜像部署Spring Boot 3.1.6的WAR包。
方案2:调整Spring Boot配置适配现有Tomcat
- 在Maven项目的
pom.xml中排除内置Tomcat依赖,添加对应版本的Tomcat Servlet API:
<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> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>10.1.18</version> <scope>provided</scope> </dependency>
- 确保Spring Boot主类继承
SpringBootServletInitializer:
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
- 重新打包WAR包后部署到现有Tomcat镜像,若仍有问题,优先尝试升级Tomcat到10.1.16+版本。
方案3:使用Spring Boot内置Tomcat运行
跳过外部Tomcat,直接打包为Jar包运行:
- 修改
pom.xml打包方式为Jar(默认即为Jar,若之前是War则调整):
<packaging>jar</packaging>
- 打包后用Corretto 17镜像运行:
docker run -p 8080:8080 -v /本地Jar包路径/app.jar:/app.jar amazoncorretto:17-alpine java -jar /app.jar
调试日志(翻译后)
at org.springframework.boot.web.servlet.DynamicRegistrationBean.register(DynamicRegistrationBean.java:122) ~[spring-boot-3.1.6.jar:3.1.6] at org.springframework.boot.web.servlet.RegistrationBean.onStartup(RegistrationBean.java:52) ~[spring-boot-3.1.6.jar:3.1.6] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:236) ~[spring-boot-3.1.6.jar:3.1.6] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:192) ~[spring-boot-3.1.6.jar:3.1.6] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161) ~[spring-boot-3.1.6.jar:3.1.6] ... 49 个更多栈帧 13-Dec-2023 17:42:00.709 严重 [main] org.apache.catalina.startup.HostConfig.deployWAR 部署Web应用归档文件[/usr/local/tomcat/webapps/samplespring.war]时出错 java.lang.IllegalStateException: 启动子容器出错 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:729) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:747) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:976) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1950) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:777) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:427) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1657) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:946) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:886) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:926) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:795) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) 引起原因: org.apache.catalina.LifecycleException: 启动组件[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/documentprocessor]]失败 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:726)
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

