在嵌入式 Jetty 中使用 JSP 標籤庫(JSTL)時,常遇到 PWC6188: Cannot load tag library 錯誤。這是 Jetty 的已知問題,需通過反射清理 TldScanner 的系統 URI 緩存來修復。
JSP 頁面聲明:
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
Tomcat 正常,但嵌入式 Jetty 啟動後拋出異常。
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.0.7.v20131107</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.0.7.v20131107</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
<version>9.0.7.v20131107</version>
</dependency>
public class JettyServer {
public static void main(String[] args) throws Exception {
System.setProperty("DWPROJECTNO", "resource");
System.setProperty("DWENV", "dev");
startJettyServer(80, "/");
}
public static void startJettyServer(int port, String contextPath) throws Exception {
// 關鍵修復:清理 TldScanner 系統 URI 緩存
Field f = TldScanner.class.getDeclaredField("systemUris");
f.setAccessible(true);
((Set<?>) f.get(null)).clear();
f.setAccessible(false);
Server server = new Server(port);
WebAppContext webContext = new WebAppContext("src/main/webapp", contextPath);
webContext.setClassLoader(Thread.currentThread().getContextClassLoader());
webContext.setDefaultsDescriptor("src/test/resources/jetty-webdefault.xml");
server.setHandler(webContext);
server.setStopAtShutdown(true);
server.start();
server.join();
}
}
Jetty 的 TldScanner 內部維護一個 systemUris 集合,預設包含標準 JSTL URI,導致嵌入式模式下無法正確掃描項目內的標籤庫。通過反射清空該集合,強制 Jetty 重新掃描 WebApp 上下文中的 TLD 文件,從而正確加載 JSTL。