Подтвердить что ты не робот

Получение NoSuchMethodError: javax.servlet.ServletContext.addServlet в Spring Загрузка при запуске приложения Spring MVC

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

ContainerBase: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:188)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    ... 6 more
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)Ljavax/servlet/ServletRegistration$Dynamic;
    at org.springframework.boot.context.embedded.ServletRegistrationBean.onStartup(ServletRegistrationBean.java:166)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:214)
    at org.springframework.boot.context.embedded.tomcat.ServletContextInitializerLifecycleListener.lifecycleEvent(ServletContextInitializerLifecycleListener.java:54)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 6 more
4b9b3361

Ответ 1

Я решил его исключить транзитивную зависимость сервлета-api.

В моем случае это было com.github.isrsal: spring -mvc-logger

<dependency>
    <groupId>com.github.isrsal</groupId>
    <artifactId>spring-mvc-logger</artifactId>
    <version>0.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Ответ 2

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

java -verbose:class -jar foo.jar | grep javax.servlet.ServletContext

где foo.jar - это толстый JAR, вырабатываемый Gradle или Maven. Например, класс ServletContext может получать чтение из более раннего servlet-api JAR в каталоге расширений JDK вместо зависимостей Maven или Gradle.

Результат команды выглядит примерно так:

$ java -verbose:class -jar build/libs/foo-0.2.3.jar | grep javax.servlet.ServletContext
[Loaded javax.servlet.ServletContext from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]
[Loaded javax.servlet.ServletContextListener from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]
[Loaded javax.servlet.ServletContextAttributeListener from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]

Ответ 3

gradle.

У меня была аналогичная проблема в моем java-банке, который по какой-то причине привел с собой старую версию javax.servlet.ServletContext, которая позже была загружена моим модулем spring -boot, а не его собственным поставляемым классом, тем самым a NoSuchMethodError

Я исправил его, отредактировав build.gradle моего модуля lib:

configurations {
    provided.all*.exclude group: 'javax.servlet'
}

Ответ 4

У меня это было в spring -boot webapp, только на сервере развертывания (отлично работало на моей локальной машине). Я решаю это, добавляя:

<dependencies>
<!-- … -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<!-- … -->

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html

Ответ 5

Для всех, кто не смог решить это, исключив servlet-api, вот альтернатива:

Оказывается, Spring Boot по умолчанию для Tomcat 8. Если вы используете другую версию Tomcat и хотите исправить эту ошибку, просто добавьте свою версию tomcat в свойства pom:

<properties>
    <tomcat.version>7.0.63</tomcat.version>
</properties> 

Ответ 6

У меня возникла эта проблема при попытке запустить загрузочный сервер spring во время тестов (используя gradle + spock). Я проследил эту проблему в библиотеке wiremock.

Это зафиксировало это:

testCompile('com.github.tomakehurst:wiremock:1.58') {
    exclude module: 'servlet-api' // this exclude fixed it
}

FYI

gradle dependencies

показывает (сокращенно):

\--- com.github.tomakehurst:wiremock:1.58
     +--- org.mortbay.jetty:jetty:6.1.26
          +--- org.mortbay.jetty:jetty-util:6.1.26
          \--- org.mortbay.jetty:servlet-api:2.5-20081211

Древняя (2008) org.mortbay.jetty:servlet-api jar содержит версию ServletContext, которая несовместима с версией 1.3.2 загрузки spring (работала нормально, по крайней мере, до 1.2.6).

Ответ 7

Я использовал Gradle и то, что сработало для меня:

configurations {
    all*.exclude group: '', module: 'servlet-api'
}

Он обрезает дерево зависимостей желаемым образом.

Ответ 8

Я работал с Hadoop 2.7.2 с помощью Spring -boot, следующие зависимости Hadoop используют javax.servlet, что предотвращает запуск встроенной версии tomcat. Ниже исключений в моем POM исправлена ​​проблема.

                                    <dependency>
                                    <groupId>org.apache.hadoop</groupId>
                                    <artifactId>hadoop-hdfs</artifactId>
                                    <version>2.7.2</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>
                                <dependency>
                                    <groupId>org.springframework.data</groupId>
                                    <artifactId>spring-data-hadoop-boot</artifactId>
                                    <version>2.3.0.RELEASE-hadoop26</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>

                                <dependency>
                                    <groupId>org.apache.hadoop</groupId>
                                    <artifactId>hadoop-common</artifactId>
                                    <version>2.7.2</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>slf4j-log4j12</artifactId>
                                            <groupId>org.slf4j</groupId>
                                        </exclusion>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>

Ответ 9

В соответствии с этим решением: https://stevewall123.wordpress.com/2015/04/17/spring-boot-application-and-tomcat-error-a-child-container-failed-during-start/

Вы можете изменить версию Tomcat, установив свойство "tomcat.version":

ext['tomcat.version'] = '7.0.63' //my version of Tomcat

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
}

он работает для меня, благодаря автору этой статьи.

Приветствия:)

Ответ 10

Если вы используете STS, и вы добавили библиотеку Groovy в свой проект (Project Properties → Java Build Path → Libraries), убедитесь, что вы выбрали "No, only include groovy -all". Другой вариант "Да, включить groovy -all и bsf.jar..., servlet-2.4.jar" добавляет сервлет-2.4.jar, который конфликтует со встроенными классами tomcat8, что приводит к этой проблеме.

Ответ 11

Я использую Jetty в своем проекте и получил ту же ошибку. Моим быстрым решением было исключить встроенный Tomcat из зависимости от Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-ws</artifactId>
    <version>1.2.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Ответ 12

Я не мог отследить проблематичную ссылку, за исключением того, что знал, что это как-то попадает в мой класс-путь, поэтому вот мои 2 цента для ленивых разработчиков, использующих eclipse:

Прокрутите список зависимостей maven в дереве проектов (обычно в разделе Ресурсы Java → Библиотеки → Зависимости Maven), отследите проблемную добавленную банку, которую вы хотите исключить из вашего упакованного JAR, щелкните правой кнопкой мыши по ней → выберите Maven → Исключить артефакт Maven! Voila - автоматически исключение будет добавлено к вашему pom прямо под зависимостью, которая ссылается на него.

Шахта BTW была jcifs...

        <dependency>
        <groupId>org.codelibs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.18.2</version>
        <exclusions>
            <exclusion>
                <artifactId>servlet-api</artifactId>
                <groupId>javax.servlet</groupId>
            </exclusion>
        </exclusions>
    </dependency>

Удачи!

Ответ 13

mvn dependency:tree не обнаружил servlet-api.jar в моем пути к классам, но щелкнув правой кнопкой мыши проект (в Eclipse) и перейдя в "Путь сборки/Настройка пути сборки", было показано, что мое рабочее пространство JRE, JDK 1.7.0_51 по умолчанию, jar в каталоге jre/lib/ext (по крайней мере, в моей установке). Я попробовал и не смог удалить его из своего класса. @Pedro решение для принудительной обработки версии tomcat до 7. Так же была установлена ​​последняя версия Java 7: JDK 1.7.0_79.

Ответ 14

Я также столкнулся с этой ошибкой. У меня есть проект Maven/ Spring MVC/Spring Boot. Я использую IntelliJ как IDE, и всякий раз, когда я добавляю новые зависимости к POM.xml, среда IDE изменяет файл .iml(как и ожидалось), но что странно, что он перемещает следующую строку в начало файла:

<orderEntry type="library" name="Java EE 6-Java EE 6" level="project" />

как только это произойдет, мой проект не будет компилироваться, и я получаю ту же ошибку:

java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName() Ljava/lang/String;

просто переместив orderEntry для Java EE назад, ошибка исчезнет, ​​и я могу скомпилировать еще раз.

Ответ 15

Для быстрого решения я удалил servlet-api.jar вручную из библиотеки lib, а затем создаю приложение, и оно работает. Однако, в идеале, как было предложено Kumetix, нужно тщательно изучить до тех пор, пока зависимость, вызывающая ее загрузку в classpath.