web-dev-qa-db-fra.com

Obtention de NoSuchMethodError: javax.servlet.ServletContext.addServlet dans Spring Boot lors de l'exécution d'une application Spring MVC

Je reçois une exception inférieure lorsque j'essaie d'exécuter une application Spring MVC à l'aide de Spring boot ...

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
38
Arghya Sadhu

Si vous voulez savoir d'où la classe est chargée, essayez

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

foo.jar est le gros JAR produit par Gradle ou Maven. Par exemple, la classe ServletContext peut être lue à partir d'une ancienne servlet-api JAR dans un répertoire d'extensions JDK au lieu de vos dépendances Maven ou Gradle.

La sortie de la commande ressemble à ceci ...

$ 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!/]
27
Emerson Farrugia

Je l'ai résolu en excluant une dépendance transitive servlet-api.

Dans mon cas, c'était 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>
25
amuniz

solution gradle.

J'ai eu un problème similaire dans mon bocal de bibliothèque qui, pour une raison quelconque, a apporté avec elle une ancienne version de javax.servlet.ServletContext qui a ensuite été chargée par mon module Spring-Boot au lieu de sa propre classe fournie, provoquant une NoSuchMethodError

Je l'ai corrigé en modifiant le build.gradle de mon module lib:

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

Pour toute autre personne qui n'a pas pu le résoudre en excluant servlet-api, voici une alternative:

Il s'avère que Spring Boot est par défaut Tomcat 8. Si vous utilisez une version différente de Tomcat et que vous souhaitez corriger cette erreur, ajoutez simplement votre version Tomcat aux propriétés de pom:

<properties>
    <Tomcat.version>7.0.63</Tomcat.version>
</properties> 
7

J'ai eu ce problème en essayant de démarrer mon serveur de démarrage de printemps pendant tests (en utilisant gradle + spock). J'ai tracé le problème à la bibliothèque wiremock.

Cela l'a corrigé:

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

FYI

gradle dependencies

montre (abrégé):

\--- 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

L'ancien (2008) org.mortbay.jetty:servlet-api jar contient une version de ServletContext qui est incompatible avec la version 1.3.2 de Spring Boot (fonctionnait bien au moins jusqu'à 1.2.6).

6
Bohemian

Je l'avais dans une webapp à démarrage par ressort, uniquement sur le serveur de déploiement (fonctionnait bien sur ma machine locale). Je le résout en ajoutant:

<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

6
Shoham

J'utilisais Gradle et ce qui a fonctionné pour moi:

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

Il a coupé l'arbre de dépendance de la manière souhaitée.

5
kkonrad

J'exécutais avec Hadoop 2.7.2 en utilisant Spring-boot, les dépendances Hadoop suivantes utilisent javax.servlet qui empêchait la version Tomcat intégrée de démarrer. Ci-dessous les exclusions dans mon POM correction du problème.

                                    <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>
5
Praveen Kumar K S

Selon cette solution: https://stevewall123.wordpress.com/2015/04/17/spring-boot-application-and-Tomcat-error-a-child-container-failed-during-start/

Vous pouvez changer la version de Tomcat en définissant la propriété "Tomcat.version":

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

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

cela fonctionne pour moi, grâce à l'auteur de cet article.

À votre santé :)

3
thyzz

Si vous utilisez STS et que vous avez ajouté la bibliothèque Groovy à votre projet (Propriétés du projet -> Java Chemin de génération -> Bibliothèques), assurez-vous de sélectionner le "Non, incluez uniquement groovy -all "option. L'autre option de" Oui, inclure groovy-all et bsf.jar ..., servlet-2.4.jar "ajoute servlet-2.4.jar qui entre en conflit avec les classes Tomcat8 incorporées entraînant ce problème.

2
ghostcoder007

J'utilise Jetty dans mon projet et j'ai eu la même erreur. Ma solution rapide a été d'exclure le Tomcat intégré de la dépendance 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>
2
Olga

Je n'ai pas pu retrouver la référence problématique, sauf pour savoir qu'elle pénètre dans mon chemin de classe, alors voici mes 2 cents pour les développeurs paresseux utilisant Eclipse:

Faites défiler la liste des dépendances maven sous votre arborescence de projet (généralement sous Java Resources -> Libraries -> Maven Dependencies), suivez le pot ajouté problématique que vous souhaitez exclure de votre JAR packagé, cliquez avec le bouton droit dessus -> sélectionnez Maven -> Exclude Maven Artifact! Voila - automatiquement une exclusion sera ajoutée à votre droit sous la dépendance qui la réfère.

Le mien BTW était 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>

Bonne chance!

2
baraka

mvn dependency:tree n'a pas révélé le servlet-api.jar sur mon chemin de classe, mais en cliquant avec le bouton droit sur le projet (dans Eclipse) et en allant vers Chemin de génération / Configurer Le chemin de génération a montré que mon espace de travail par défaut JRE, JDK 1.7.0_51, avait ce pot dans son jre/lib/ext répertoire (au moins dans mon installation). J'ai essayé et échoué de le supprimer de mon chemin de classe. @ Pedro's solution de forcer la version Tomcat à 7 a fonctionné. Il en est de même pour l'installation de la dernière version de Java 7: JDK 1.7.0_79.

1
whistling_marmot

J'ai également fait face à cette erreur. J'ai un projet Maven/Spring MVC/Spring Boot. J'utilise IntelliJ comme IDE et chaque fois que j'ajoute de nouvelles dépendances au POM.xml, le IDE modifie le fichier .iml (comme prévu) mais ce qui est bizarre, il déplace la ligne suivante en haut du fichier:

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

une fois que cela se produit, mon projet ne sera pas compilé et j'obtiens la même erreur:

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

en déplaçant simplement orderEntry pour Java EE vers le bas, l'erreur disparaît et je peux compiler une fois de plus.

1
Bipin Butala

Pour une solution rapide, j'ai supprimé manuellement le servlet-api.jar de la bibliothèque et ensuite construire l'application et cela fonctionne.Toutefois, idéalement comme suggéré par Kumetix, il faut analyser jusqu'à la dépendance qui le fait se charger dans classpath.

0
road2victory