Tomcat 10部署Web项目报ServletContextListener类找不到异常求助
问题根因
该报错由Tomcat版本迭代带来的Java EE到Jakarta EE的命名空间变更导致:Oracle将Java EE捐献给Eclipse基金会后,相关规范更名为Jakarta EE,从Tomcat 10版本开始,官方默认支持Jakarta EE 9+规范,所有Servlet相关API的包名从原来的javax.servlet.*全部重命名为jakarta.servlet.*,两者的全限定类名完全不同,类加载器无法互相识别。
项目编译时引入的是javax.servlet版本的API,因此编译不会报错,但部署到Tomcat 10后,容器中只有jakarta.servlet版本的API,因此找不到代码中引用的javax.servlet.ServletContextListener类,就抛出了对应异常。
API选择规则
开发Java Web应用时,选择哪种命名空间的API完全取决于部署使用的Web容器版本:
- 若使用Tomcat 10及以上、Jetty 11及以上、GlassFish 6及以上等支持Jakarta EE 9+规范的容器,必须基于
jakarta.servlet.XXX系列API进行编译 - 若使用Tomcat 9及以下、Jetty 10及以下、传统Java EE商业服务器等兼容旧Java EE规范的容器,继续使用
javax.servlet.XXX系列API即可
针对当前场景的解决方案
当前使用的是Tomcat 10.0.13,推荐按以下步骤修复:
- 全局替换项目中所有Servlet相关的导入语句,把
javax.servlet开头的导入全部替换为jakarta.servlet,例如:
// 替换前 import javax.servlet.ServletContextListener; // 替换后 import jakarta.servlet.ServletContextListener;
- 更新构建配置中的Servlet API依赖,替换为对应Jakarta版本,注意保持scope为
provided,避免把API打包进war包,以Maven为例:
<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency>
- 清理项目后重新编译打包,部署到Tomcat即可正常触发上下文监听器。
如果暂时不想修改现有代码,也可以直接降级使用Tomcat 9版本,无需调整代码即可正常运行。
内容的提问来源于stack exchange,提问作者queeg
相关产品推荐
相关产品推荐

