You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring 6.0.11部署Tomcat10遇ClassCastException问题求助

Spring 6.0.11 部署到 Tomcat 10 时 ClassCastException 问题解决

将 Spring 4.2.4 迁移至 Spring 6.0.11 后,部署到 Tomcat 10 时抛出如下类型转换异常:

java.lang.ClassCastException: class org.springframework.web.servlet.DispatcherServlet cannot be cast to class jakarta.servlet.Servlet (org.springframework.web.servlet.DispatcherServlet is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @53bd8fca; jakarta.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @7eda2dbb)

完整异常栈信息:

SEVERE: Servlet [spring] in web application [/SpringMVCPagination] threw load() exception
java.lang.ClassCastException: class org.springframework.web.servlet.DispatcherServlet cannot be cast to class jakarta.servlet.Servlet (org.springframework.web.servlet.DispatcherServlet is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @53bd8fca; jakarta.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @7eda2dbb)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:865)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:805)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4637)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4930)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1328)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1318)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:846)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1328)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1318)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:241)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:428)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:918)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:795)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478)

问题原因

Tomcat 10 及以上版本使用 Jakarta EE API(包前缀为jakarta.servlet.*),而 Spring 4.x 依赖的是旧版 Java EE API(包前缀为javax.servlet.*)。即便 Spring 6 原生支持 Jakarta EE,迁移时若存在以下遗漏仍会触发异常:

  • 项目残留旧的javax.servlet相关依赖
  • web.xml配置仍使用Java EE命名空间
  • 类路径中同时存在javax.servlet和jakarta.servlet类,引发类加载冲突

解决步骤

1. 替换Servlet API依赖

将项目中所有javax.servlet相关依赖替换为Jakarta EE版本:

  • Maven项目:移除javax.servlet:javax.servlet-api依赖,添加:
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
    <scope>provided</scope>
</dependency>
  • 检查其他依赖(如Spring MVC、JSP API等),确保它们适配Jakarta EE(Spring 6本身已支持,重点排查第三方库)。

2. 更新web.xml配置

将web.xml的命名空间切换为Jakarta EE规范:
旧配置开头:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

替换为:

<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">

同时确认Servlet、Filter等配置的类路径正确,未引用javax.servlet下的类。

3. 排查类路径冲突

  • 清理项目target目录,重新构建
  • 执行mvn dependency:tree查看依赖树,若有依赖传递引入javax.servlet包,直接排除:
<dependency>
    <groupId>依赖组ID</groupId>
    <artifactId>依赖包ID</artifactId>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

4. 确认环境兼容性

Spring 6.0.x要求:

  • JDK版本17及以上
  • Jakarta EE 9.0+(Tomcat 10满足该要求)
    检查项目编译级别是否设置为JDK 17及以上。

内容的提问来源于stack exchange,提问作者Ramesh Reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:57:10