JSP / JSTL导致TagSupport出现NoClassDefFound错误

时间:2013-09-20 12:00:06

标签: java java-ee tomcat jstl

这个问题让我疯了几个星期了,我怀疑一旦找到它,决议就会很简单。我已经查看了StackOverflow中可以找到的每个相关答案,但还没有设法解决它,所以我希望有人能够帮助我。

为了简单起见,我在一个非常简单的网络应用程序中重新创建了这个问题,所以我希望这会让人们更容易提供帮助。

这是(简化)问题:

  • 我有一个Java EE Web应用程序,它包含一个使用Core JSTL标记库的JSP。

  • 我已经下载了两个我相信相关的JSTL罐子。这些是:

    javax.servlet.jsp.jstl-1.2.1.jarjavax.servlet.jsp.jstl-api-1.2.1.jar

  • 我已将这两个文件放在我的Tomcat lib文件夹中。

  • 在我的简化网络应用程序中,没有应用程序库(WEB-INF / lib),所以我很确定我没有在应用程序中的任何其他地方复制文件。

  • 我在web.xml中引用了servlet 2.5。

当我运行应用程序时,我收到以下错误(编辑为包括完整堆栈跟踪):

java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagSupport
    java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:295)
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    java.lang.ClassLoader.loadClass(ClassLoader.java:295)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.Class.forName0(Native Method)
    java.lang.Class.forName(Class.java:249)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1701)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    org.apache.jasper.compiler.Parser.parseCustomTag(Parser.java:1223)
    org.apache.jasper.compiler.Parser.parseElements(Parser.java:1452)
    org.apache.jasper.compiler.Parser.parse(Parser.java:138)
    org.apache.jasper.compiler.ParserController.doParse(ParserController.java:242)
    org.apache.jasper.compiler.ParserController.parse(ParserController.java:102)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:198)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

这是我的jsp文件index.jsp

<%-- Created by IntelliJ IDEA. --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test JSP</title>
</head>
<body>
    <h1>
        Test Heading
    </h1>
    <c:if test="true">
        <p>True</p>
    </c:if>
</body>
</html>

这是我的web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">
    <servlet>
        <servlet-name>myjsp</servlet-name>
        <jsp-file>/index.jsp</jsp-file>
    </servlet>
    <servlet-mapping>
        <servlet-name>myjsp</servlet-name>
        <url-pattern>/myjsp</url-pattern>
    </servlet-mapping>
</web-app>

最后,对于它的价值,这里是我的Tomcat lib文件夹中的文件列表:

annotations-api.jar
catalina-ant.jar
catalina-ha.jar
catalina-tribes.jar
catalina.jar
ecj-4.2.2.jar
el-api.jar
jasper-el.jar
jasper.jar
javax.servlet.jsp.jstl-1.2.1.jar
javax.servlet.jsp.jstl-api-1.2.1.jar
jsp-api.jar
servlet-api.jar
tomcat-api.jar
tomcat-coyote.jar
tomcat-dbcp.jar
tomcat-i18n-es.jar
tomcat-i18n-fr.jar
tomcat-i18n-ja.jar
tomcat-jdbc.jar
tomcat-util.jar

注:

在我的原始应用程序中,我使用的是3.0版web.xml,但是我使用2.5获得了相同的错误。

我发现如果我从

更改jsp文件中的标记lib声明
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

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

我得到完全相同的错误,这让我感到惊讶。我原本以为我会在声明中没有“/ jsp”的情况下得到像TLD文件没有找到的类型错误,所以我想知道这是否是一个线索?

如果我注释掉核心标签(<c:if ...>)jsp工作并显示文本。

我希望这里有足够的信息供人们帮助。如果您需要进一步澄清,请告诉我。

3 个答案:

答案 0 :(得分:0)

根据我使用jarfinder.com发现的内容,javax.servlet.jsp.tagext.TagSupport类应该在您的jsp-api.jar文件中。

如果没有,那么这可能是Tomcat,JSP和JSTL版本之间的不匹配。

答案 1 :(得分:0)

首先,正确的core taglib名称空间uri是

http://java.sun.com/jsp/jstl/core

jstl-1.2.jar/META-INF/c.tld中声明。

其次,我认为你不需要javax.servlet.jsp.jstl-api-1.2.1.jar。我认为这是多余的。

你应该

Tomcat已经提供了

servlet-apijsp-api。我建议您尝试删除Tomcat安装并安装新安装。只添加你缺少的东西,即。 jstl

在您自己的应用程序的jsp-api文件夹中,三次检查您是否没有上述任何一种罐子,尤其是lib

答案 2 :(得分:0)

首先,感谢所有试图帮助解决这个问题的人。我现在已经解决了错误,并且解决方案不是我期望任何人发现的。我不能接受你的答案,因为他们没有正确的解决方案,但我不能提高他们的作用,因为我没有足够的特权 - 对不起!

问题在于:

在Mac上,作为支持Java的文件夹结构的一部分,有一个名为

的文件夹
/Library/Java/Extensions

我不完全确定这个文件夹应该用于什么但是我误解了它的用途并且一直用它来保存jar文件然后我会通过我的IDE(IntelliJ IDEA)拉入我的项目。 / p>

我下载的文件实际上是Tomcat在我的Web应用程序中使用的库(例如Tag Libraries)。在不同的时间,各种项目中都有大量的文件,我假设这不会成为一个问题,因为文件夹只是我存储东西的存储库,然后拉出我需要的东西。项目

我并没有假装准确地了解在低级别发生的事情,但实际上,当我在Tomcat下运行我的Web应用程序时,Tomcat调用JVM以便在JVM中运行,它包含/其类路径中的Library / Java / Extensions文件夹。

据我了解,Tomcat没有使用Java类路径,并且有自己的类加载器功能。

这样做的结果是Tomcat在我的Web应用程序库中找到了正确版本的类(例如jsp-api.jar),但是在调用(非Tomcat)类时,JVM在错误的地方找到了一些类(即... / Extensions文件夹)并且它们不兼容,因此会产生错误。

我知道这有点模糊 - 我无意再进行任何调查,以确切了解发生了什么,因为我已经花了数周时间;关键是当我从... / Extensions文件夹中删除所有的jar并从另一个文件夹中的jar重建我的库时(我只使用了我的下载文件夹),一切都终于有效了。

我不知道那里有什么教训 - 我很惊讶这已经花了多长时间以及浪费了多少时间(这种情况经常发生)是一个相对简单的问题。

如果有人碰巧对幕后发生的事情有了更多的技术把握,并且愿意添加一个很棒的评论。