JSTL breaks on GoogleAppEngine's development server, but works on remote server
As the title says, my JSTL tags don't work on my development server, but do work on Google's actual server.
I simplified the code to the bare bone to make sure there wasn't anything wrong with the code, so here's what I've got.
JSP
<%@ page language=开发者_运维百科"java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Page Title</title>
</head>
<body>
<c:choose>
<c:when test="${2+2==4}">sum works</c:when>
<c:otherwise>sum doesn't work</c:otherwise>
</c:choose>
</body>
My configuration is as follows (which I think is correct and which works on Google's server): I'm using
- Eclipse IDE
- Servlet 2.5
- No jstl jar added to WEB-INF\lib
- No tld added anywhere
- No taglib reference
on web.xml
However, I have also tried a number of combinations of the following and none of them worked:
- jstl-1.2.jar added to the build path
- c.tld added to WEB-INF
- taglib reference added to web.xml
Error is below:
HTTP ERROR 500
Problem accessing /index.html. Reason:
javax/servlet/jsp/tagext/TagSupport
Caused by:
java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/TagSupport
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:927)
at java.lang.ClassLoader.loadClass(ClassLoader.java:298)
at com.google.appengine.tools.development.DevAppServerClassLoader.loadClass(DevAppServerClassLoader.java:87)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at com.google.appengine.tools.development.DevAppServerClassLoader.loadClass(DevAppServerClassLoader.java:87)
...
Strangely, though, <c:out value="${blah}"/>
works both on the development and remote servers. other core tags don't work. If I try to add fmt tags, they don't work as well.
Any ideas?
You need to drop JSTL JAR in /WEB-INF/lib
or at least in the /lib
folder of the servletcontainer which you're using on local development.
You should not extract the JAR and clutter the webapp with loose TLD files and also not reference it anywhere in web.xml
. Undo everything if you have done it. You should also not have the need to manually add it to Eclipse build path. Just dropping in /WEB-INF/lib
folder ought to be enough.
See also:
- Our JSTL wiki page
The fact that google searches were returning no useful information already indicated that this problem was unique to my configuration.
Alas, I finally managed to figure out what was wrong and I'm just posting the solution in case someone comes across this problem, which dreaded me for days.
Turned out I had added Tomcat's servlet-api.jar and jstl jar into Eclipse's default JRE library to avoid having to add them each time into WEB-INF\lib (i.e. Window > Preferences > Java > Installed JREs > Edit > Add External Jar).
Once I started developing in GAE, this configuration started causing a conflict with AppEngine's own servlet-api.jar and jstl jars.
The answer was simply to remove the Tomcat jars from the JRE library.
精彩评论