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

JDK升级至17后嵌入式Jetty无法解析JSTL TLD的问题求助

解决方案:Jetty 9.2.x + JDK17 无web.xml环境下JSTL解析问题

1. 修正Maven依赖(避免冲突,确保正确的JSTL绑定)

Jetty的apache-jstl依赖已经包含了标准JSTL 1.2的实现,无需单独引入jstl-1.2.jar,否则会导致类路径冲突。保留以下依赖即可:

<dependencies>
    <!-- 嵌入式Jetty核心 -->
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.2.23.v20171218</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-webapp</artifactId>
        <version>9.2.23.v20171218</version>
    </dependency>
    <!-- Apache Jasper JSP引擎 + JSTL支持 -->
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>apache-jsp</artifactId>
        <version>9.2.23.v20171218</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>apache-jstl</artifactId>
        <version>9.2.23.v20171218</version>
    </dependency>
</dependencies>

2. 编程式配置Jetty的JSP/JSTL加载逻辑(无web.xml替代方案)

因为项目没有web.xml和WEB-INF,需要在嵌入式Jetty的启动代码中手动配置JSP Servlet,并指定TLD扫描路径,确保JSTL的标签库能被识别:

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
import org.apache.jasper.servlet.JspServlet;

public class JettyStarter {
    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        WebAppContext webApp = new WebAppContext();
        
        // 设置项目根路径(根据你的实际资源位置调整)
        webApp.setResourceBase("src/main/webapp");
        webApp.setContextPath("/");
        
        // 配置JSP Servlet
        ServletHolder jspHolder = new ServletHolder("jsp", JspServlet.class);
        jspHolder.setInitParameter("fork", "false");
        jspHolder.setInitParameter("xpoweredBy", "false");
        // 关键:指定JSTL的TLD扫描路径,从依赖的jar包中读取
        jspHolder.setInitParameter("org.eclipse.jetty.jsp.tldscan", "classpath:/META-INF/c.tld,classpath:/META-INF/fmt.tld");
        webApp.addServlet(jspHolder, "*.jsp");
        
        // 确保类加载器能优先访问JSTL的类
        webApp.setParentLoaderPriority(true);
        
        server.setHandler(webApp);
        server.start();
        server.join();
    }
}

3. 解决JDK17模块化访问限制

JDK17的模块化系统会限制非模块化代码(如Jetty 9.2.x)访问javax包的类,需要在启动时添加VM参数:

--add-modules java.servlet.jsp.jstl,java.xml.bind,java.activation
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.servlet/javax.servlet=ALL-UNNAMED
--add-opens java.servlet.jsp/javax.servlet.jsp=ALL-UNNAMED
--add-opens java.servlet.jsp.jstl/javax.servlet.jsp.jstl.core=ALL-UNNAMED

这些参数会开放Jetty和Jasper需要访问的模块,避免反射或类加载失败。

4. (可选)升级Jetty版本(推荐长期解决方案)

Jetty 9.2.x是2017年的版本,对JDK11+的兼容性存在先天不足。如果上述方法仍无效,建议升级到Jetty 9.4.x(支持JDK8-JDK17),新版本对模块化JDK的支持更好,且无需复杂的TLD手动配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:03:18