cannot load JSTL taglib within embedded Jetty serv

2019-01-18 20:19发布

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?

10条回答
一纸荒年 Trace。
2楼-- · 2019-01-18 20:57

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

查看更多
别忘想泡老子
3楼-- · 2019-01-18 21:00

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.

查看更多
戒情不戒烟
4楼-- · 2019-01-18 21:06

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.

查看更多
趁早两清
5楼-- · 2019-01-18 21:10

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);
}
查看更多
smile是对你的礼貌
6楼-- · 2019-01-18 21:10

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$");
查看更多
贼婆χ
7楼-- · 2019-01-18 21:12

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.

查看更多
登录 后发表回答