升级Spring Boot3+Tomcat10.1后JSP自定义标签加载失败:找不到指定类
问题核心
升级到Spring Boot 3和Tomcat 10.1后,自定义JSP标签<t:baseLayout>无法加载,报错:
Caused by: java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.Tag
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1437) ~[catalina.jar:10.1.7]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1245) ~[catalina.jar:10.1.7]
... 182 common frames omitted
原因是Tomcat 10.1属于Jakarta EE 9+生态,所有原javax.servlet相关API已完全迁移至jakarta.servlet命名空间,你的自定义标签实现或配置仍依赖旧的javax包API。
解决步骤
1. 更新自定义标签的Java实现类
将所有JSP标签相关的javax导入替换为jakarta:
- 原导入:
javax.servlet.jsp.tagext.Tag、javax.servlet.jsp.tagext.TagSupport、javax.servlet.jsp.tagext.BodyTag等 - 替换为:
jakarta.servlet.jsp.tagext.Tag、jakarta.servlet.jsp.tagext.TagSupport、jakarta.servlet.jsp.tagext.BodyTag等
示例代码修改:
// 旧代码 import javax.servlet.jsp.tagext.TagSupport; public class BaseLayoutTag extends TagSupport { // 标签逻辑 } // 新代码 import jakarta.servlet.jsp.tagext.TagSupport; public class BaseLayoutTag extends TagSupport { // 标签逻辑 }
2. 更新标签库描述符(TLD)文件
修改TLD文件的命名空间和版本,适配Jakarta EE规范:
- 替换原TLD根元素的XML命名空间为Jakarta EE 3.0版本
- 确保
<tag-class>指向更新后的jakarta包下的标签类
示例TLD修改:
<!-- 旧TLD开头 --> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 新TLD开头 --> <taglib 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-jsptaglibrary_3_0.xsd" version="3.0"> <!-- 同时确保tag-class指向正确的类 --> <tag> <name>baseLayout</name> <tag-class>com.yourpackage.BaseLayoutTag</tag-class> <!-- 其他配置 --> </tag>
3. 检查JSP页面的taglib引用
确保JSP中引入自定义标签的指令指向更新后的TLD,且URI与TLD文件中的<uri>一致:
<%@taglib prefix="t" uri="/WEB-INF/tlds/baseLayout.tld" %>
4. 清理旧依赖
检查项目依赖中是否残留javax.servlet.jsp-api或其他旧javax相关依赖,排除这些依赖避免冲突:
// 示例:排除旧依赖 implementation('some-third-party-lib') { exclude group: 'javax.servlet.jsp', module: 'javax.servlet.jsp-api' }
补充说明
你的JSTL部分已经正确迁移(使用jakarta.tags.coreURI并引入Jakarta版依赖),但自定义标签未同步完成命名空间迁移,导致Tomcat无法找到旧javax包下的API类。
内容的提问来源于stack exchange,提问作者René Höhle

