Ошибка: ядро ​​сервлета не загружено... Класс нарушения: javax/servlet/Servlet.class

Я получаю следующую ошибку:

INFO: validateJarFile (C:\dev\server\tomcat6\webapps Sempedia\WEB-INF\lib\servlet-api.jar) - jar не загружен. См. Описание сервлета 2.3, раздел 9.7.2. Класс нарушения: javax/servlet/Servlet.class

Существующие ресурсы говорят, что это связано с конфликтом с servlet.jar или в моем случае с именем servlet-api.jar. Я удалил все другие проекты из папки /webapps, я взял файл servlet-api.jar, который был в каталоге tomcat6/lib, и добавил это и только к пути построения проекта, поэтому я не вижу, как там по-прежнему является конфликтом.

Когда я пытаюсь запустить приложение, я получаю следующую трассировку стека.

org.apache.jasper.JasperException: невозможно компилировать класс для JSP:

Произошла ошибка в строке: 22 в сгенерированном java файле Метод getJspApplicationContext (ServletContext) undefined для типа JspFactory

StackTrace:

org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)     org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)     org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:439)     org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)     org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)     org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)     org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586)     org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)     org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)     org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)     javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Ответ 1

Это признак загрязнения класса. Библиотеки API JSP/Servlet являются зависимыми от реализации приложений и зависят от Tomcat 6 в папке Tomcat/lib и должны перемещаться и дублироваться в другом месте без возможности. Это рецепт проблем с переносимостью и столкновений при загрузке классов, как вы уже встречались. Библиотеки в webapp имеют приоритет при загрузке классов. Если там встречается servlet-api.jar, он, в свою очередь, ищет там свои зависимости, но они, по-видимому, там отсутствовали.

Вы должны удалить любые библиотеки, зависящие от приложений, из webapp Webapp/WEB-INF/lib. Вы должны только помещать в него библиотеки, специфичные для Webapp. Храните библиотеки приложений, зависящие от приложений, в собственном классе путей по умолчанию, который является Tomcat/lib в вашем случае. Держите его нетронутым. Вы можете в большинстве случаев добавлять библиотеки, которые вы хотите распространять среди всех webapps там, или даже лучше, настроить shared.loader в Tomcat/conf/catalina.properties для этого.

Также удалите любые специфичные для приложений и специфичные для Webapp библиотеки из папок JDK/lib и JRE/lib, если они есть. Я слишком часто видел, что некоторые стартеры перемещают/копируют библиотеки там, потому что "это иначе не компилируется". Вы никогда не должны копировать библиотеки, не относящиеся к JRK/JRE. Это рецепт проблем с переносимостью. При компиляции классов с javac вы должны использовать аргумент -cp для указания зависимых библиотек.

Обновить: в случае IDE (вы, похоже, используете его, поскольку говорите о "пути сборки" ), вам необходимо связать веб-проект с сервером приложений. Например, в Eclipse у вас есть возможность сделать это во время создания динамического веб-проекта. Перед созданием проекта вам необходимо интегрировать экземпляр сервера в Eclipse. Вы можете сделать это через представление Servers (при условии, что вы используете разработчиков Eclipse для Java EE, а затем обновите). Вы также можете изменить его впоследствии через запись "Серверы" в свойствах проекта. Выберите тот, который вы хотите использовать в качестве сервера по умолчанию, а затем его библиотеки будут автоматически включаться в путь построения проекта. Абсолютно нет необходимости копировать/перемещать их где-то в другом месте. См. Также Как импортировать API javax.servlet в проект Eclipse?

Ответ 2

Как говорят другие ответы, это связано с тем, что ваша WAR включает в себя классы API сервлета, но это не должно делать.

Если вы используете Maven для создания своего проекта, вам захочется сказать Maven, чтобы сделать API сервлета доступным при компиляции и тестировании, но не включать его в WAR. Как сообщает документация Maven о области зависимостей, вы должны использовать область provided для API Servlet:

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>

Вам также может потребоваться явно исключить API-интерфейс Servlet в качестве транзитивной зависимости, если некоторые из ваших зависимостей вытягивают в Servlet API как зависимость от компиляции:

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>frob-driver-core</artifactId>
        <version>1.0.1</version>
        <exclusions>
            <exclusion>
                <artifactId>servlet-api</artifactId>
                <groupId>javax.servlet</groupId>
            </exclusion>
        </exclusions>
    </dependency>

Ответ 3

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

http://www.jcp.org/aboutJava/communityprocess/final/jsr053/

и убедитесь сами. Раздел 9.7.2 находится на физической странице 63.

Servlet 2.3 - довольно старая версия, показывающая древнюю версию Tomcat. Есть ли какая-то конкретная причина, по которой вы не используете более новую?

Ответ 4

Первое сообщение об ошибке, которое вы получили, это то, что Tomcat не нужно загружать баннер сервлета, поскольку он уже имеет один и хочет избежать конфликтов.

Обычно вы можете безопасно игнорировать предупреждение. Если вы не хотите, чтобы он появлялся, вам нужно переместить кувшин сервлета из вашего проекта, а не использовать тот из tomcat. Принимая tomcat один и помещая его в ваш проект, вам удалось убедить tomcat загрузить его из вашего webapp, а не из того места, где он его ожидал, что вызвало проблему загрузчика классов, как указано в ответе BalusC.

Изменить: вышеописанное было отредактировано, чтобы уточнить, что происходит, когда вы помещаете сервлет-api jar из tomcat в ваш webapp (и атрибут BalusC).

Ответ 5

На самом деле у меня была такая ошибка и приложение. не удалось начать, потому что по некоторым причинам некоторые из фляг в WEB-INF/lib имели расширение .JAR (верхний регистр) вместо .JAR. Поэтому убедитесь, что все банки действительны.

Ответ 6

Исключения и provided зависимости не будут работать в дочерних проектах.

Если вы используете наследование в проектах Maven, вы должны включить эту конфигурацию в родительский pom.xml файл. У вас будет раздел <parent>...</parent> в вашем pom.xml, если вы используете наследование. Таким образом, у вас будет что-то подобное в вашем родителе pom.xml:

<groupId>some.groupId</groupId>
<version>1.0</version>
<artifactId>someArtifactId</artifactId>
<packaging>pom</packaging>
<modules>
    <module>child-module-1</module>
    <module>child-module-2</module>
</modules>
<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>