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

Spring Boot MVC升级Java20/Tomcat10.1后第三方TLD库报错求助

问题:升级Spring Boot到Java 20/Tomcat 10.1后出现ClassNotFoundException

将Spring Boot应用升级至Java 20/Tomcat 10.1版本后,因依赖第三方TLD库,运行时抛出如下错误:

Servlet.service() for servlet [jsp] threw exception
java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.BodyTagSupport
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:496)
    at java.base/java.lang.Class.forName(Class.java:475)
    at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:121)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:496)
    at java.base/java.lang.Class.forName(Class.java:475)
    at org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader.loadFromParent(TomcatEmbeddedWebappClassLoader.java:113)
    at org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader.doLoadClass(TomcatEmbeddedWebappClassLoader.java:86)
    at org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader.loadClass(TomcatEmbeddedWebappClassLoader.java:70)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1165) ...

当前POM中的相关依赖:

<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
</dependency>

<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
</dependency>

原因

Tomcat 10.1基于Jakarta EE 9+规范,所有Servlet/JSP相关API的包名已从javax.*迁移至jakarta.*。错误中缺失的javax.servlet.jsp.tagext.BodyTagSupport是旧版javax下的类,说明你的第三方TLD库仍依赖旧版javax API,或当前依赖配置缺少必要的兼容桥接。

解决方案

1. 添加Jakarta到Java EE的桥接依赖

Tomcat提供了专门的桥接包,用于兼容依赖旧javax API的库:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jakartaee-migration</artifactId>
    <version>1.0.0</version>
    <scope>provided</scope>
</dependency>

如果是Spring Boot环境,也可以通过调整Tomcat嵌入依赖来实现兼容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-el</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>10.1.x</version> <!-- 替换为你使用的Tomcat 10.1具体版本 -->
    <classifier>jakarta</classifier>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <version>10.1.x</version> <!-- 替换为你使用的Tomcat 10.1具体版本 -->
    <classifier>jakarta</classifier>
</dependency>

2. 升级第三方TLD库到Jakarta兼容版本

检查第三方TLD库是否有支持Jakarta EE 9+的版本,直接升级是最彻底的解决方案,可避免桥接包带来的潜在兼容性问题。

3. 调整tomcat-embed-jasper的作用域

当前tomcat-embed-jasper的scope设为provided,开发环境中可能导致依赖缺失。建议开发阶段改为compile,生产环境再恢复为provided:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>compile</scope>
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:44:57