1

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

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

这是(简化的)问题:

  • 我有一个 Java EE Web 应用程序,它包含一个使用核心 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 文件未找到类型错误的信息,所以我想知道这是否是一个线索?

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

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

4

4 回答 4

1

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

问题是这样的:

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

/Library/Java/Extensions

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

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

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

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

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

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

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

如果有人碰巧对幕后发生的事情有更多的技术掌握,并且愿意添加评论,那就太好了。

于 2013-09-30T12:09:29.987 回答
0

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

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

于 2013-09-20T12:27:59.667 回答
0

首先,正确的coretaglib 命名空间 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-api并且jsp-api应该已经由 Tomcat 提供。我建议尝试删除您的 Tomcat 安装并安装一个新的。只添加你所缺少的,即。jstl.

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

于 2013-09-20T18:38:51.643 回答
0

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

例如,删除:

<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %>
于 2021-11-11T16:14:51.893 回答