从Tomcat9迁移至Tomcat10后加载javax.servlet.http.HttpServlet失败排查
问题
我的Servlet曾在Tomcat9上正常运行,现尝试迁移至Tomcat10。已完成以下操作:
- 从构建路径移除
javax.servlet-api-3.1.0.jar,添加jakarta.servlet-api-5.0.0.jar - 修改代码中所有
javax.servlet相关引用:
//import javax.servlet.*; //import javax.servlet.http.*; import jakarta.servlet.*; import jakarta.servlet.http.*;
- 使用Ant构建项目,javac已成功将类文件生成到Tomcat10的webapps目录:
destdir="/var/lib/tomcat10/webapps/${app_version}/WEB-INF/classes"
但Servlet无法启动,localhost日志报错:
27-Jun-2024 15:23:00.211 SEVERE [https-openssl-nio-8080-exec-198] org.apache.catalina.core.ApplicationContext.log HTMLManager: Error starting [/tomcat_app] org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/tomcat_app]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:419) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:186) ... Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet ... Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet ...
项目结构复杂,想排查是哪个类/代码/配置导致加载javax.servlet.http.HttpServlet。
补充:发现项目中有类继承自com.google.gwt.user.server.rpc.RemoteServiceServlet,该类实现了javax.servlet.Servlet,怀疑是问题根源。尝试改用com.google.gwt.user.server.rpc.jakarta.RemoteServiceServlet(位于gwt-servlet-jakarta.jar)但找不到下载渠道,想问现阶段GWT是否适配Tomcat10?
解决方案
一、排查哪个类引用了javax.servlet
- 检查依赖库:遍历项目
WEB-INF/lib目录,用解压工具查看每个jar包内容,排查是否有包含javax.servlet相关类的旧版本第三方框架jar。 - 扫描字节码定位引用:
- 用
javap命令:对WEB-INF/classes下的所有class文件执行javap -c 类全路径 | grep javax.servlet,查看哪个类的字节码里残留了javax包引用。 - 用JD-GUI工具:将class文件或jar包导入工具,直接搜索
javax.servlet关键词,快速定位引用的类。
- 用
- 检查配置与构建脚本:
- 查看
web.xml里的<servlet>、<filter>等配置项,确认类全限定名是否都改成了jakarta相关的路径。 - 检查Ant构建脚本,确认是否有遗漏更新的依赖——比如是否把旧的
javax.servlet-api或含javax.servlet的第三方jar打包进了WEB-INF/lib。
- 查看
- 开启Tomcat详细日志:修改Tomcat的
conf/logging.properties,将org.apache.catalina.level设为FINE,重启后查看日志,会输出完整的类加载轨迹,能明确看到是哪个类触发了javax.servlet.http.HttpServlet的加载请求。
二、GWT适配Tomcat10的问题
GWT从2.10版本开始支持Jakarta EE规范,对应提供了适配Jakarta的gwt-servlet-jakarta依赖:
- 该jar包可从Maven中央仓库获取,用Ant构建的话,直接搜索
gwt-servlet-jakarta下载对应2.10及以上的稳定版jar包即可。 - 替换原有的
gwt-servlet.jar,同时把项目中继承RemoteServiceServlet的类改为继承com.google.gwt.user.server.rpc.jakarta.RemoteServiceServlet。 - 注意:项目中其他GWT服务器端类(比如自定义RPC过滤器)也要检查,确认是否需要替换为Jakarta版本的对应类。
内容的提问来源于stack exchange,提问作者Gauthier
相关产品推荐
相关产品推荐

