You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring-web模块与Tomcat 10的兼容性及迁移ClassCastException问题咨询

Hey there! Let's tackle your questions about Spring Web and Tomcat 10 compatibility, plus that tricky ClassCastException you're hitting after migration.

Spring Web 与 Tomcat 10 的兼容性
  • 核心兼容性逻辑: Tomcat 10 基于 Jakarta EE 9+ API 构建,所有相关包名从javax.servlet切换为jakarta.servlet。而旧版 Spring Web(比如 Spring Framework 5.x)依赖传统 Java EE 的javax包,因此无法直接兼容 Tomcat 10。
  • 兼容的 Spring 版本: 从Spring Framework 6.0开始,Spring 生态全面迁移到 Jakarta EE API,所以 Spring Web 6.0 及以上版本完全兼容 Tomcat 10(包括 10.0.x 和 10.1.x 分支)。如果使用 Spring Boot,基于 Spring Framework 6 的 Spring Boot 3.0+ 版本也原生支持 Tomcat 10。
迁移到 Tomcat 10 后出现 ClassCastException 的原因与解决方法

报错原因解析

你遇到的报错:

java.lang.ClassCastException: org.springframework.web.filter.DelegatingFilterProxy cannot be cast to jakarta.servlet.Filter

本质是包名切换导致的接口不匹配:

  • Tomcat 9 要求过滤器实现javax.servlet.Filter接口
  • Tomcat 10 要求过滤器实现jakarta.servlet.Filter接口
    旧版 Spring Web(5.x 及以下)中的DelegatingFilterProxy实现的是旧的javax.servlet.Filter,在 Tomcat 10 环境下,容器期望的是jakarta包下的接口实例,因此抛出类型转换异常。

解决办法

方案1:升级到兼容 Jakarta 的 Spring 版本(推荐)

这是长期稳定的解决方案:

  1. 将项目升级到Spring Framework 6.0+Spring Boot 3.0+
  2. 把所有javax相关依赖替换为jakarta版本(例如将javax.servlet-api替换为jakarta.servlet-api 4.0+)
  3. 检查代码中直接引用javax.servlet类的地方,统一替换为jakarta.servlet对应的类

方案2:使用 Tomcat 10 的遗留桥接(临时 workaround)

如果暂时无法升级 Spring,Tomcat 10 提供了遗留桥接功能来运行基于javax包的应用:

  • 使用官方的tomcat-jakartaee-migration工具自动转换项目依赖为桥接包
  • 或手动添加 Tomcat 的 Jakarta EE 桥接依赖(比如tomcat-jakarta-servlet-api)到项目中
  • 注意:这只是短期过渡方案,桥接实现可能存在潜在兼容问题,长期来看还是建议升级到 Spring 6.x/Spring Boot 3.x

内容的提问来源于stack exchange,提问作者YN Raja

火山引擎 最新活动