【问题标题】:JSP / JSTL causes NoClassDefFound error for TagSupportJSP / JSTL 导致 TagSupport 的 NoClassDefFound 错误
【发布时间】:2013-09-25 19:29:40
【问题描述】:

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

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

这是(简化的)问题:

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

  • 我已经下载了我认为相关的两个 JSTL jar。它们是:

    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文件中的标签库声明从

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

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

我得到完全相同的错误,这让我感到惊讶。我原以为如果声明中没有“/jsp”,我会得到类似 TLD 文件未找到类型错误的信息,所以我想知道这是否是一个线索?

如果我注释掉核心标签 (&lt;c:if ...&gt;),jsp 工作并显示文本。

我希望这里有足够的信息可以帮助人们。如果您需要任何进一步的说明,请告诉我。

【问题讨论】:

    标签: java jakarta-ee tomcat jstl


    【解决方案1】:

    对于在更新到 Jakarta EE 9 后看到此错误的任何人,请确保您没有使用依赖项 org.webjars:webjars-taglib 并从您的 JSP 文件中删除相关标签。

    例如,删除:

    <%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %>
    

    【讨论】:

      【解决方案2】:

      首先,感谢所有为此提供帮助的人。我现在已经解决了这个错误,而且解决方案不是我期望任何人发现的。我无法接受您的答案,因为它们不是正确的解决方案,但我也无法将它们评为有帮助,因为我没有足够的权限 - 对此感到抱歉!

      问题是这样的:

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

      /Library/Java/Extensions
      

      我不确定该文件夹的用途,但我误解了它的用途,并一直使用它来保存 jar 文件,然后我将通过我的 IDE (IntelliJ IDEA) 将其拉入我的项目。

      我下载的文件实际上是 Tomcat 在我的网络应用程序中使用的库(例如标签库)。在不同的时间有来自不同项目的大量文件,我认为这不会是一个问题,因为该文件夹只是我存储东西的存储库,然后拉入我的项目所需的东西。

      我不会假装完全理解在低级别发生的事情,但本质上,当我在 Tomcat 下运行我的 Web 应用程序时,Tomcat 会调用 JVM 以便在 JVM 中运行,它包括 /Library/类路径中的 Java/Extensions 文件夹。

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

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

      我知道这有点含糊——我不打算再做任何调查来查明到底发生了什么,因为我已经为此花费了数周时间;关键是,当我从 .../Extensions 文件夹中删除所有 jar 并从另一个文件夹中的 jar 重建我的库(我只是使用了我的下载文件夹)时,一切最终都奏效了。

      我不知道其中的教训是什么 - 我很惊讶这花了多长时间以及我在这个相对简单的问题上浪费了多少时间(通常是这种情况)。

      如果有人碰巧对幕后发生的事情有更专业的了解,并且愿意添加评论,那就太好了。

      【讨论】:

        【解决方案3】:

        首先,正确的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。我认为这是多余的。

        你应该有

        servlet-apijsp-api 应该已经由 Tomcat 提供。我建议尝试删除您的 Tomcat 安装并安装一个新的。只添加你所缺少的,即。 jstl.

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

        【讨论】:

        • 谢谢。我已经仔细检查了所有内容,并且正如您所建议的那样。在这个应用程序中,我没有应用程序的 lib 文件夹,它是一个 jsp 文件。我已经尝试过重新安装一次 Tomcat,但我将再次安装。一个问题 - Tomcat 文件归哪个用户所有重要吗?在我读过的安装说明中,它说将所有者更改为安装用户,但我希望机器上的任何用户都可以使用安装,所以就离开了。据我所知,它只需要可读(除了需要可执行的脚本)。对吗?
        • 顺便说一下 - Sotirios 和 @Stephen - 我没有足够的权限为你 +1,但你的回复很有帮助。
        • @Auspice 运行脚本的人必须能够读取/写入/执行 Tomcat 文件。如果脚本由auspice 执行,但webapp 归root 所有,那么您将无法访问它。
        • @Auspice 您始终可以通过选中旁边的复选标记来接受答案。如果答案帮助您解决了问题,请执行此操作。您只能选择一个答案。
        • 我现在已经尝试了很多东西,但仍然没有任何进展。目前让我感到困惑的是,在我的 JSP 文件中,无论我使用 java.sun.com/jsp/jstl/core 还是 java.sun.com/jstl/core,我都不会得到不同的错误在我的 IDE 或运行时。我不明白为什么我的 IDE (Intellij IDEA) 在我使用错误的声明时没有给我一个错误,或者为什么我在运行时得到的错误是相同的。这是否意味着某个地方必须有一个 TLD 文件,其 URI 为 java.sun.com/jstl/core?如果是这样,我不知道它可能在哪里。
        【解决方案4】:

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

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

        【讨论】:

        • 感谢您的回复。我应该提到(因为我走的是同一条路线)我已经检查了 jsp-api.jar 并且那里有一个 TagSupport 类。如果我删除 jsp-api.jar,那么我会得到一个不同的错误,与找不到也在该文件中的 JspFactory 相关。课程在那里但我得到 NoClassDefFound 的事实似乎有点奇怪。我同意这种不匹配,但尝试了一些方法,包括完全重新安装 Tomcat,所以我很难找到我没有想到的东西。
        • 嗯……有更早的例外吗?如果先前尝试初始化该类或它所依赖的其他类之前在静态初始化中失败并出现未经检查的异常,则您可以获得NoClassDefFoundError
        • 我已更新问题以包含完整的根本原因堆栈跟踪。正如您所建议的,我认为问题不一定是该类不存在,而是在尝试加载它时发生了其他一些错误。我已经开始查看堆栈跟踪中调用的一些类的 Tomcat 源代码,但我希望避免进入这个级别。你知道我是否可以直接调试 Tomcat 以查看崩溃发生时的上下文吗?
        猜你喜欢
        • 2021-05-08
        • 1970-01-01
        • 2017-03-29
        • 1970-01-01
        • 2016-02-02
        • 2011-04-02
        • 2013-04-28
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多