2013-09-20 2 views
1

Эта проблема сводит меня с ума в течение нескольких недель, и я подозреваю, что разрешение, как только я нахожу это, будет простым. Я посмотрел на каждый соответствующий ответ, который я могу найти в StackOverflow, но не смог его решить, поэтому я надеюсь, что кто-то сможет мне помочь.JSP/JSTL вызывает ошибку NoClassDefFound для TagSupport

Я попробовал проблему в очень простом веб-приложении для простоты, поэтому я надеюсь, что это облегчит людям помощь.

Здесь (упрощенно) проблема:

  • У меня есть веб-приложение Java EE, которая содержит единственную JSP, которая использует библиотеку тегов JSTL ядра.

  • Я загрузил две банки JSTL, которые, я считаю, актуальны. К ним относятся:

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

  • Я поместил эти два файла в моей Tomcat Lib папки.

  • В моем упрощенном веб-приложении нет библиотеки приложений (WEB-INF/lib), поэтому я уверен, что я не дублировал файлы в другом месте приложения.

  • Я ссылаюсь на сервлет 2.5 в web.xml.

Когда я запустить приложение, я получаю следующее сообщение об ошибке (отредактирован, чтобы включить полный трассировки стека):

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.

Я обнаружил, что если я изменить тег Lib заявление в файле Jsp от

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

в

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

я получаю точно такую ​​же ошибку, что меня удивляет. Я бы подумал, что я получу что-то вроде файла TLD, не нашел ошибку типа без «/ jsp» в объявлении, поэтому я задаюсь вопросом, является ли это ключом?

Если я прокомментирую основные теги (<c:if ...>) jsp работает и отображает текст.

Надеюсь, здесь есть информация для людей, которые могут помочь.Если вам нужно какое-либо уточнение, дайте мне знать.

ответ

0

Во-первых, спасибо всем, кто попытался помочь в этом. Теперь я разрешил ошибку, и решение не было чем-то, что я ожидал, чтобы кто-нибудь заметил. Я не могу согласиться с вашими ответами, поскольку они были неправильным решением, но я не могу раскрыть их как полезную, поскольку у меня нет достаточных привилегий - извините!

Проблема заключалась в следующем:

На Mac, как часть структуры папок для поддержки Java, есть папка под названием

/Library/Java/Extensions 

Я не совсем уверен, что эта папка должна но я неправильно истолковал его цель и использовал его для хранения файлов jar, которые затем я мог бы подключить к своему проекту через мою IDE (IntelliJ IDEA).

Файлы, которые я скачивал, были фактически библиотеками, которые будут использоваться в моем веб-приложении Tomcat (например, тегами). В разное время там было множество загрузок из разных проектов, и я предполагал, что это не будет проблемой, поскольку папка была всего лишь хранилищем для хранения вещей, а затем втягивала то, что мне нужно для моего проекта.

Я не претендую на то, чтобы точно понимать, что происходит на низком уровне, но по сути, когда я запускаю свое веб-приложение под Tomcat, Tomcat вызывает JVM для запуска и внутри JVM, он включает в себя/Library/Java/Extensions в своем классе.

Как я понимаю, Tomcat не использует путь Java classpath и имеет свои собственные функции загрузчика классов.

Результат состоит в том, что Tomcat находил правильные версии классов (например, jsp-api.jar) в моей библиотеке веб-приложений, но при вызове классов (не Tomcat) JVM находил некоторые классы в неположенном месте (например, в папке .../Extensions), и они были несовместимы, что создавало ошибки.

Я знаю, что это немного расплывчато - я не собираюсь проводить какое-либо расследование, чтобы точно выяснить, что произошло, поскольку я провел недели на этом; Дело в том, что когда я удалил все банки из папки .../Extensions и перестроил свои библиотеки из банок в другой папке (я просто использовал папку с загрузкой), все в конечном итоге сработало.

Я не знаю, какой урок есть - я поражен тем, сколько времени это заняло и сколько времени я потратил на то, что было (как это часто бывает), относительно простой проблемой.

Если у кого-то есть более техническое понимание того, что происходит под обложками, и хотелось бы добавить комментарий, который был бы замечательным.

0

Основываясь на том, что я нашел с помощью jarfinder.com, класс javax.servlet.jsp.tagext.TagSupport должен находиться в вашем файле jsp-api.jar.

Если нет, то, возможно, это несоответствие между версиями Tomcat, JSP и JSTL.

+0

Спасибо, что ответили. Я должен был упомянуть (потому что я пошел по тому же пути), что я проверил jsp-api.jar, и там есть класс TagSupport. Если я удалю jsp-api.jar, тогда я получаю другую ошибку, связанную с тем, что не обнаруживаю JspFactory, который также находится в этом файле. Тот факт, что класс есть, но я получаю NoClassDefFound, кажется немного странным. Я согласен с несоответствием, но попробовал несколько вещей, включая полную переустановку Tomcat, поэтому я пытаюсь найти то, о чем я не думал. – Auspice

+0

Хммм ... есть ли ранее исключение? Вы можете получить «NoClassDefFoundError», если предыдущая попытка инициализировать класс или какой-либо другой класс, от которого он зависит, ранее не выполнялась при статической инициализации с помощью неконтролируемого исключения. –

+0

Я обновил вопрос, чтобы включить полную трассировку стека корня. Как вы полагаете, проблема заключается не в том, что класс не существует, но возникает другая ошибка при попытке загрузить его. Я начал изучать исходный код Tomcat для некоторых классов, вызванных в трассировке стека, но я надеялся избежать перехода на этот уровень. Вы знаете, могу ли я действительно отлаживать Tomcat напрямую, чтобы увидеть контекст, когда происходит сбой? – Auspice

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. Я думаю, что это избыточно.

Вы должны

servlet-api и jsp-api уже должны быть предоставлены Tomcat. Я предлагаю удалить вашу установку Tomcat и установить новую. Добавляйте только то, что вам не хватает, т.е. jstl.

Тройной проверить, что у вас нет ни одного из вышеуказанных банок, особенно jsp-api, в папке вашего собственного приложения lib.

+0

Спасибо. Я дважды проверил все, и это, как вы предлагаете. В этом приложении у меня нет папки lib для приложения, это один файл jsp. Я уже пытался повторно установить Tomcat один раз, но я собираюсь сделать это снова. Один вопрос - имеет ли значение, к какому пользователю принадлежат файлы Tomcat? В инструкциях по установке, которые я прочитал, мы говорим об изменении владельца для установки пользователем, но я хочу, чтобы установка была пригодна для использования любым пользователем на машине, поэтому просто оставила ее. Насколько я знаю, это просто нужно читать (кроме скриптов, которые должны быть исполняемыми). Это правильно? – Auspice

+0

Кстати - Sotirios и @Stephen - у меня нет достаточных привилегий для +1, но ваши ответы были полезны. – Auspice

+0

@Auspice Файлы Tomcat должны быть удобочитаемыми/записываемыми/исполняемыми исполняющим скрипты. Если скрипт выполним «auspice», но webapp принадлежит «root», то вы не сможете получить к нему доступ. –

 Смежные вопросы

  • Нет связанных вопросов^_^