无法在嵌入式Jetty服务器中加载JSTL taglib

时间:2010-01-27 23:18:26

标签: java jetty jstl taglib embedded-jetty

我正在编写一个在嵌入式Jetty实例中运行的Web应用程序。

当我尝试执行JSTL语句时,收到以下异常:

  

org.apache.jasper.JasperException:/index.jsp(1,63)PWC6188:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:http://java.sun.com/jsp/jstl/core

我在类路径上有以下jar:

  • 蚁1.6.5.jar
  • 蚁1.7.1.jar
  • ant-launcher-1.7.1.jar
  • 芯3.1.1.jar
  • 码头-6.1.22.jar
  • 码头-util的-6.1.22.jar
  • 的jsp-2.1-6.1.14.jar
  • 的jsp-API-2.1.jar
  • JS​​TL-1.2.jar
  • servlet的API-2.5-20081211.jar
  • servlet的API-2.5-6.1.14.jar
  • 标准1.1.2.jar

我的web.xml如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>  
    <web-app 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 h77p://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"  
    version="2.4">  
    <display-name>test</display-name>  
</web-app>

我的代码如下所示:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<html>  
    <body>  
        <h2>Hello World!</h2>  
        <%= new java.util.Date() %><br/>  
        ${1+2}<br/>  
        <c:out var="${5+9}"/><br/>  
    </body>  
</html>

我开始使用这样的嵌入式Jetty服务器:

Server server = new Server(80);  
WebAppContext context = new WebAppContext("pig-1.0-SNAPSHOT.war","/");
server.addHandler(context);
server.start();

我花了两天时间尝试使用jar文件,web.xml配置和标记库声明的各种组合,但无济于事。

如何在完整的JSTL支持下启动并运行嵌入式Jetty服务器?

10 个答案:

答案 0 :(得分:8)

Jetty 8.0,在使用jetty:run时作为默认值推送,具有servlet API 3.0。从该版本的标准开始,应该包含JSTL标准,并且这些标记库不能在webapp类路径中,只能在标准类路径中。但是,8.0.0.M0忘了包含它们。

指定7.1.4.v20100610对我有帮助。

答案 1 :(得分:8)

jstl taglib必须位于服务器类路径上。您可以在启动服务器之前将类加载器添加到当前的类加载器链。这是start.jar启动jetty服务器时使用的原则。

ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
URL urlTaglibs = new File(PATH_TO_TAGLIBS).toURI().toURL();
URLClassLoader newClassLoader = new URLClassLoader(new URL[]{urlTaglibs},currentClassLoader);
Thread.currentThread().setContextClassLoader(newClassLoader);

server.start();

您还应该将其添加到java start命令行参数。

答案 2 :(得分:5)

  
      
  • JS​​TL-1.2.jar
  •   
  • 标准1.1.2.jar
  •   

这碰撞了。删除standard-1.1.2.jar。您应该standard-1.1.2.jar 仅使用 jstl-1.1.2.jar。从JSTL 1.2开始,标准JAR已合并到JSTL JAR中,从而生成一个jstl-1.2.jar文件。

答案 3 :(得分:3)

@Drew 谢谢德鲁。它有效。我一直在谷歌上搜索并最终来到这里。我的错误是: 我正在使用

                 <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>jstl</artifactId>
                     <version>1.1.2</version>
                     <scope>provided</scope>
                </dependency>

我从上面改为

           <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
             <version>1.2</version>
             <scope>provided</scope>
        </dependency>

它开始工作了。我也使用了我删除的jstls依赖。

答案 4 :(得分:2)

我在Jetty 7上遇到了同样的问题, 我通过让Jetty搜索TLD来解决它:

我是通过在上下文中设置属性来完成的:

Server server = new Server(80);  
WebAppContext context = new WebAppContext("pig-1.0-SNAPSHOT.war","/");
context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", 
    ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$");
server.addHandler(context);
server.start();

参考http://wiki.eclipse.org/Jetty/Howto/Configure_JSP#Using_JSTL_Taglibs_for_Jetty_7.x_and_8.x 有关详细信息。

在我的项目上(使用maven),我在JAR“org.apache.taglibs.standard.glassfish-1.2.0.v2011120803.jar”上有标准TLD,理论上它足以用作ContainerIncludeJarPattern的值以下模式:

".*/org\\.apache\\.taglibs\\.standard\\.glassfish-1\\.2\\.0\\.v201112081803\\.jar"

它实际上是有效的,它确认了jetty在哪里找到了标签库,但我更倾向于保留我在上面链接的wiki.eclipse.org页面上找到的先前模式。

如果要包含自定义标记库,可能需要扩展模式。

答案 5 :(得分:2)

我遇到了同样的问题,发现http://java.sun.com/jsp/jstl/core被视为单个系统URI,并且所有尝试定义它的taglib定义都被忽略(但是在引用时,无论如何都会发生错误)。

在启动Jetty之前我使用了以下内容,现在它可以正常工作:

try {
    Field f = TldScanner.class.getDeclaredField("systemUris");
    f.setAccessible(true);
    ((Set)f.get(null)).clear();
} catch (Exception e) {
    throw new RuntimeException("Could not clear TLD system uris.",e);
}

答案 6 :(得分:1)

两步:

1)为服务器添加注释支持

//启用解析web.xml和jetty-env.xml的jndi相关部分,#server is

org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");

2)将follow属性添加到WebAppContext

context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\\.jar$");

答案 7 :(得分:0)

在您的web.xml中,尝试更改“h77p://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”以“http://”开头并查看是否可以解决错误。

但是,这可能不是根本原因,因为我在JSP中使用jetty-maven-plugin和JSTL taglib头时遇到了同样的错误:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  

PWC6188:绝对的uri:   http://java.sun.com/jsp/jstl/core   无法在任何web.xml中解析   或者使用它部署的jar文件   应用

我正在使用SpringSource Tool Suite中的开箱即用的Spring MVC模板,所以我不确定为什么Jetty的Maven插件会呛到它。

<build>
   <plugins>
      <plugin>
         <groupId>org.mortbay.jetty</groupId>
         <artifactId>jetty-maven-plugin</artifactId>
      </plugin>
   </plugins>
</build>
<repositories>
     <repository>
       <id>maven2-repository.dev.java.net</id>
       <name>Java.net Repository for Maven</name>
       <url>http://download.java.net/maven/2/</url>
       <layout>default</layout>
     </repository>
</repositories>

只有javax.servlet:jstl:1.2列在我的POM依赖项中,因为它现在废弃了taglibs:standard:1.1.2,这是上面给出的建议。

答案 8 :(得分:0)

我也有同样的问题。我通过添加以下代码来修复它:

public static final String[] TLD_JAR_NAMES = new String[]{"sitemesh", "spring-webmvc", "shiro-web", "springside-core"};
...
JettyFactory.setTldJarNames(server, TLD_JAR_NAMES);

也许你可以尝试一下。请将TLD_JAR_NAMES替换为您的真实TLD Jar名称。

答案 9 :(得分:0)

通过添加以下代码,我摆脱了问题:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>jasper</artifactId>
    <version>6.0.29</version>
</dependency>

我正在使用jetty-runner 8。