公司旧项目,使用<#assign shi=JspTaglibs["http://shiro.apache.org/tags"]/>来引入自定义标签,使用Java代码进行启动时,提示TLD文件无法加载。
原因可能是:
Jetty的jsp处理引擎来自于Glassfish,要求JSF标签必须位于Jetty容器的classpath中,不能位于Web应用的classpath中,而Jetty的WebAppClassLoader优先使用父classloader加载类,导致tld文件都被加载到父classloader中,在Jetty的classpath中根本扫描不到,所以会出现找不到tld文件的情况。 |
尝试在启动代码中处理,但是不生效,文章后边的启动代码中,注释部分为尝试的解决方法,都未成功。
最后通过使用相对路径引入标签解决:<#assign shi=JspTaglibs["/WEB-INF/tld/shiro.tld"]/>
Jetty启动代码:
public static final String[] TLD_JAR_NAMES = new String[] { "sitemesh", "spring-webmvc", "shiro-web", "springside-core", "shiro" };
public static void main(String[] args) {
/* fix jetty8.x, jetty 9.x can't load jstl library */
// try { // Field f = TldScanner.class.getDeclaredField("systemUris"); // f.setAccessible(true); // ((Set<?>) f.get(null)).clear(); // f.setAccessible(false); // } catch (NoSuchFieldException e) { // e.printStackTrace(); // } catch (IllegalAccessException e) { // e.printStackTrace(); // }
// 服务器的监听端口 Server server = new Server(9999); // 设置在JVM退出时关闭Jetty的钩子。 server.setStopAtShutdown(true); // 关联一个已经存在的上下文 WebAppContext context = new WebAppContext(); // 设置描述符位置 context.setDescriptor("src/main/webapp/WEB-INF/web.xml"); // 设置Web内容上下文路径 context.setResourceBase("src/main/webapp"); // 设置上下文路径 context.setContextPath("/"); context.setParentLoaderPriority(true);
// WebAppContext context = new WebAppContext("src/main/webapp", "/");
// context.setClassLoader(Thread.currentThread().getContextClassLoader()); // context.setDescriptor("src/main/webapp/WEB-INF/web.xml");
server.setHandler(context);
// JettyFactory.setTldJarNames(server, TLD_JAR_NAMES); // context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*/[^/]*servlet-api-[^/]*\.jar$|.*/javax.servlet.jsp.jstl-.*\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\.jar$"); // Server server = JettyFactory.createServerInSource(9999, "/");
try { server.start(); // server.join(); } catch (Exception e) { e.printStackTrace(); }
System.out.println("server is start"); }
/** * 设置除jstl-*.jar外其他含tld文件的jar包的名称. * jar名称不需要版本号,如sitemesh, shiro-web */ public static void setTldJarNames(Server server, String... jarNames) { WebAppContext context = (WebAppContext) server.getHandler(); List<String> jarNameExprssions = Lists.newArrayList(".*/jstl-[^/]*\.jar$", ".*/.*taglibs[^/]*\.jar$"); for (String jarName : jarNames) { jarNameExprssions.add(".*/" + jarName + "-[^/]*\.jar$"); }
context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", StringUtils.join(jarNameExprssions, '|'));
}
|