需匹配JDK与Tomcat版本:Tomcat 9支持JDK 8–11,10.1+支持11–17,11需JDK 17+;检查JAVA_HOME和实际java版本一致;正确创建setenv.sh/.bat配置JVM参数;确认webapps/ROOT存在且端口未被占用;Spring Boot 3.x适配Tomcat 10+的Jakarta EE。

Tomcat 启动失败:java.lang.UnsupportedClassVersionError 怎么办
这是最常见的环境错配问题,本质是 JDK 版本高于 Tomcat 编译所支持的最低版本。比如用 JDK 17 运行 Tomcat 9(仅支持到 Java 11),就会报这个错。
- 查 Tomcat 官方文档确认其支持的
JDK范围:Tomcat 9 → JDK 8–11;Tomcat 10.1+ → JDK 11–17;Tomcat 11 → JDK 17+ - 运行
java -version和$JAVA_HOME/bin/java -version,确认终端实际使用的 JDK 是否与JAVA_HOME一致 - Windows 下检查系统环境变量是否被 IDE(如 IntelliJ)或脚本覆盖;macOS/Linux 注意
~/.zshrc或/etc/profile中的export JAVA_HOME=...是否指向正确路径
setenv.sh / setenv.bat 不生效?内存和编码配置要这样加
Tomcat 默认不带 setenv 文件,必须手动创建,且位置、权限、命名都严格限定。
- Linux/macOS:在
$CATALINA_HOME/bin/下新建setenv.sh,首行加#!/bin/sh,并执行chmod +x setenv.sh - Windows:在
%CATALINA_HOME%\bin\下新建setenv.bat,不能是 .txt 后缀 - 关键配置示例(避免中文乱码和 OOM):
export JAVA_OPTS="-Xms512m -Xmx1024m -Dfile.encoding=UTF-8"
- 不要写成
JVM_OPTS或CATALINA_OPTS(后者只影响启动脚本自身,不传给 JVM)
访问 http://localhost:8080 显示 404,但 catalina.out 没报错
不是启动失败,而是 Tomcat 默认不部署任何应用——连首页 ROOT 都可能被删了或未解压。
- 检查
$CATALINA_HOME/webapps/目录下是否存在ROOT文件夹(或ROOT.war);若只有空文件夹,需从原始 Tomcat 包中复制一份回来 - 确认
conf/server.xml中Connector的port确实是8080,且没被其他进程占用(可用lsof -i :8080或netstat -ano | findstr :8080查) - 如果用 IDE 启动(如 IDEA 的 Tomcat 插件),它可能绕过
webapps,改用临时部署路径,此时应看 IDE 控制台输出的实际部署路径,而非默认webapps
Spring Boot 打包成 WAR 后部署到 Tomcat 报 NoClassDefFoundError: javax/servlet/ServletContext
这是依赖范围冲突:Spring Boot 默认把 Servlet API 设为 provided,但 Tomcat 10+ 改用 Jakarta EE 命名空间,javax.* 已废弃。
立即学习“Java免费学习笔记(深入)”;
- Tomcat 9 及以下:保留
spring-boot-starter-web,无需改动 - Tomcat 10.1+:必须升级 Spring Boot 至
3.x,并使用spring-boot-starter-web(自动适配jakarta.servlet.*) - 若坚持用 Spring Boot 2.x + Tomcat 10+,需手动替换所有
javax.servlet为jakarta.servlet,并排除旧依赖:javax.servlet javax.servlet-api
setenv 文件的隐藏规则、以及 Jakarta 迁移这类命名空间断裂点——这些细节不报错,但会让整个流程静默失败。










