开发者

cannot load JSTL taglib within embedded Jetty server

I am writing a web application that runs within an embedded Jetty instance.

When I attempt to execute a JSTL statement, I receive the following exception:

org.apache.jasper.JasperException: /index.jsp(1,63) PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

I have the following jars on the classpath

  • ant-1.6.5.jar
  • ant-1.7.1.jar
  • ant-launcher-1.7.1.jar
  • core-3.1.1.jar
  • jetty-6.1.22.jar
  • jetty-util-6.1.22.jar
  • jsp-2.1-6.1.14.jar
  • jsp-api-2.1.jar
  • jstl-1.2.jar
  • servlet-api-2.5-20081211.jar
  • servlet-api-2.5-6.1.14.jar
  • standard-1.1.2.jar

My web.xml looks like this:

<?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>

My code looks like this:

<%@ 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>

I started my embedded Jetty server like this:

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

I spent the past two days experimenting with various combinations of jar files, web.xml configurations, and tag library declarations, but to no avail.

How can I get an embedded Jetty server up and running with full JSTL support?


Jetty 8.0, which has pushed as the default when you use jetty:run, has servlet API 3.0. As of that version of the standard, JSTL standard is supposed to be included, and these taglibs cannot be in the webapp classpath, only the standard classpath. However, 8.0.0.M0 forgot to include them.

Specifying 7.1.4.v20100610 helped for me.


The jstl taglibs must be on server classpath. You can add a classloader to current classloader chain before start the server. That's the principle used by start.jar when it start a jetty server.

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();

You should also add it to java start command line argument.


  • jstl-1.2.jar
  • standard-1.1.2.jar

This collides. Remove the standard-1.1.2.jar. You should use standard-1.1.2.jar only with jstl-1.1.2.jar. Since JSTL 1.2 the standard JAR has been merged into JSTL JAR, resulting in a single jstl-1.2.jar file.


@Drew Thanks Drew. It works.I had been googling for this and end up here.What my mistake was : I was using

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

I changed it from above to

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

and it got working. Also I was using jstls dependency which I removed.


I got the same problem on Jetty 7, I solved it by enabling Jetty to search for TLD:

I did it by setting an attribute on the context:

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();

Refer to http://wiki.eclipse.org/Jetty/Howto/Configure_JSP#Using_JSTL_Taglibs_for_Jetty_7.x_and_8.x for further details.

On my project (using maven), I have standard TLDs are on the JAR "org.apache.taglibs.standard.glassfish-1.2.0.v2011120803.jar" and theoretically it would be enough to use as value for ContainerIncludeJarPattern the following pattern:

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

It actually works and it is a confirmation of where do jetty found the tag libs, but I've preferred to leave the previous pattern which I found on the wiki.eclipse.org page linked above.

It may be required to extend the pattern if you want to include custom tag libs.


I had the same problem and found out that http://java.sun.com/jsp/jstl/core is regarded as the single system URI and all taglib definitions that try to define it are ignored (but when referenced, an error occurs anyway).

I used the following before starting the Jetty and now it works:

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);
}


Two step:

1)add annotation support for the server

//Enable parsing of jndi-related parts of web.xml and jetty-env.xml, #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) add the follow attribute to the WebAppContext

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


In your web.xml, try changing "h77p://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" to start with "http://" and see if that fixes the error.

However, that may not be the underlying cause, since I had that same error when using jetty-maven-plugin and JSTL taglib header in my JSP:

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

PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

I'm using an out-of-the-box Spring MVC template from SpringSource Tool Suite, so am not sure why the Maven plugin for Jetty chokes on it.

<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>

And only javax.servlet:jstl:1.2 is listed in my POM's dependencies, since it now obsoletes taglibs:standard:1.1.2, which was a suggestion given above.


I also had the same problems. I fixed it by adding the below code:

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

Maybe you can try it. Please replace TLD_JAR_NAMES with your real TLD Jar names.


By adding the following code I got rid of the problem:

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

I am using jetty-runner 8.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜