Tomcat9升10启动报javax.servlet.ServletRequestListener类找不到
Tomcat 9升级Tomcat 10启动报
ClassNotFoundException: javax.servlet.ServletRequestListener解决方案 核心根因
报错的直接来源是你引入的JSF 2.2版本本身内置javax命名空间引用,未适配Tomcat 10采用的Jakarta EE规范。
你在项目源码、pom配置里做的全局javax替换,只能覆盖自己写的代码和显式声明的依赖坐标,改不到第三方jar包内部编译好的字节码引用。你当前用的com.sun.faces:jsf-api:2.2.20、com.sun.faces:jsf-impl:2.2.20是Java EE 7时代的组件,内部所有servlet、生命周期相关的类引用全是javax.*前缀,Tomcat 10启动时扫描到这些监听器、Servlet相关的引用,就会报找不到javax.servlet包下类的错。
修复步骤
- 移除旧版不兼容JSF依赖
删除pom.xml中原有2.2版本的jsf-api、jsf-impl两个依赖,这两个版本没有做Jakarta命名空间适配,完全无法在Tomcat 10环境运行。 - 替换为Jakarta适配版JSF实现
引入适配Jakarta EE规范的Mojarra(原Sun/Oracle JSF参考实现迁移后的版本)依赖,根据你用的Tomcat小版本选对应版本:- Tomcat 10.0.x(对应Jakarta EE 9)用3.x版本:
<dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>3.0.4</version> </dependency>
- Tomcat 10.1.x(对应Jakarta EE 10)用4.x版本:
<dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>4.0.6</version> </dependency>
注意:不要再单独引入jsf-api、jsf-impl两个坐标,新版已经把api和实现合并到同一个jakarta.faces依赖里了。
- 清理编译残留重新打包
执行mvn clean命令删除target目录下所有旧编译产物,再重新执行打包命令,避免旧版本的class文件残留到新的war包里。 - 排查其他隐性不兼容依赖
如果替换JSF后还是报同类错,直接解压最终生成的war包,检查WEB-INF/lib目录下的第三方jar:凡是涉及web层拦截、监听器、Servlet扩展的组件,都要确认是Jakarta适配版本,常见容易漏的旧版依赖包括低版本Shiro、低版本Spring Security、旧版文件上传组件等。
快速校验方法
启动前可以用javap命令抽查lib目录下jar里的类引用,只要发现类的常量池里还存在javax/servlet/开头的类引用,对应的jar就是没做适配的问题源,替换成对应Jakarta版本即可。
内容的提问来源于stack exchange,提问作者ConfusedUbuntist
相关产品推荐
相关产品推荐

