40

I am getting below exception when I am trying to run a Spring MVC application using 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
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107
  • Can You post code snippet please ? – user3145373 ツ Jun 06 '14 at 11:17
  • What dependencies are you using? – geoand Jun 06 '14 at 11:21
  • 4
    Check your servlet version that web server support, and servlet version that you implement in your application(it can be found in web.xml). The method `addServlet()` is supported only in servlet 3.0. – Wundwin Born Jun 06 '14 at 11:57
  • 2
    Looks like you have an older version of tomcat or of the servlet API on the classpath. Use one of the available tools to look at your classpath (mvn dependency:tree, gradle dependencies, etc.). – Dave Syer Jun 06 '14 at 18:43
  • Yeah I can see servlet Api 2.5 in my classpath but I did not mention any such dependency in my pom..So how come this is coming in my classpath any what to do to make sure that servlet api 3.0 is used in my project – Arghya Sadhu Jun 08 '14 at 08:19
  • @Dave Syer.....I have now javax.servlet-api-3.1.0.jar in my classpath..but still I get the above exception – Arghya Sadhu Jun 08 '14 at 11:58

16 Answers16

29

If you want to find out where the class is being loaded from, try

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

where foo.jar is the fat JAR produced by Gradle or Maven. For example, the ServletContext class could be getting read from an older servlet-api JAR in a JDK extensions directory instead of your Maven or Gradle dependencies.

The output of the command looks something like this...

$ 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!/]
Emerson Farrugia
  • 11,153
  • 5
  • 43
  • 51
  • 4
    I prefer this answer because it gets you to the bottom of the problem. All the other ones are "me too I had this and I solved it by...". So if you have the same problem due to a different cause, you can't troubleshoot with the other answers. This is the best useful all-around answer. – ETL Aug 11 '16 at 17:32
  • `mvn dependency:tree | grep servlet-api` – kinjelom Mar 30 '20 at 14:37
27

I solved it excluding a transitive servlet-api dependency.

In my case, it was 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>
amuniz
  • 3,292
  • 2
  • 20
  • 22
  • I had the same issue and for me the servlet 2.3 dependency came from telnetd-x:2.1.1 as part of **spring-boot-starter-web** artifact-id. – randominstanceOfLivingThing Oct 22 '14 at 01:24
  • Thanks! I have the identical problem, only that I have it happen in a jar I'm producing. so, I prefer to exclude `javax.servlet` once from the dependencies coming with my artifact, instead of manually excluding it from all my other modules which depend on it. Did you by any chance find a way to that? – kumetix Apr 08 '15 at 09:46
  • @kumetix There is a hack to do it in Maven: Create your own artifact javax.serlet:servlet-api with version string 0.99-do-not-include. And define this exact version in – Grogi Nov 25 '15 at 11:58
  • 1
    I solved it by excluding `javax.servlet` dependency from `google-cloud` dependency – Halil Jan 27 '17 at 11:15
23

gradle solution.

I had a similar problem in my lib jar which for some reason brought with it an old version of javax.servlet.ServletContext which was later loaded by my spring-boot module instead of its own supplied class, by that causing a NoSuchMethodError

I fixed it by editing the build.gradle of my lib module :

configurations {
    provided.all*.exclude group: 'javax.servlet'
}
kumetix
  • 1,032
  • 1
  • 12
  • 18
9

For anyone else who couldn't solve it by excluding servlet-api , here is an alternative:

It turns out Spring Boot defaults to Tomcat 8. If you're running a different version of Tomcat and would like to fix this error, just add your tomcat version to the pom properties:

<properties>
    <tomcat.version>7.0.63</tomcat.version>
</properties> 
Pedro Hoehl Carvalho
  • 2,183
  • 2
  • 19
  • 25
  • 1
    After hours of trying to run the basic project (https://github.com/spring-guides/tut-spring-security-and-angular-js/tree/master/basic) from the Spring security and Angular tutorial (https://spring.io/guides/tutorials/spring-security-and-angular-js/), on STS 3.7.2, this was the only solution that worked for me. It ran fine with mvn spring-boot:run, but not through the IDE with tomcat 8. – whistling_marmot Jan 03 '16 at 14:08
8

I had this in a spring-boot webapp, only in the deployment server (was running fine on my local machine). I solve it by adding:

<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

Shoham
  • 7,014
  • 8
  • 40
  • 40
7

I had this problem when trying to start my spring boot server during tests (using gradle + spock). I traced the problem to the wiremock library.

This fixed it:

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

FYI

gradle dependencies

shows (abridged):

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

The ancient (2008) org.mortbay.jetty:servlet-api jar contains a version of ServletContext that is incompatible with version 1.3.2 of spring boot (worked OK at least up to 1.2.6).

Bohemian
  • 412,405
  • 93
  • 575
  • 722
6

I was using Gradle and what worked for me:

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

It trimmed dependency tree in desired way.

kkonrad
  • 1,262
  • 13
  • 32
  • thanks, it helped to solve my problem. finally I searched for dependency which introduced the 'servlet-api' with `gradle dependencies` and then I used standard gradle exclude method – Michal Moravcik Nov 13 '15 at 17:58
6

I was running with Hadoop 2.7.2 using Spring-boot, the following Hadoop dependencies uses javax.servlet which prevented the embedded tomcat version to start. Below exclusions in my POM fixed the issue.

                                    <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>
Praveen Kumar K S
  • 3,024
  • 1
  • 24
  • 31
4

According to this solution: https://stevewall123.wordpress.com/2015/04/17/spring-boot-application-and-tomcat-error-a-child-container-failed-during-start/

You can change the Tomcat version by setting the "tomcat.version" property:

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

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

it works for me, thanks to the author of that article.

Cheers :)

thyzz
  • 683
  • 1
  • 9
  • 14
4

I couldn't track down the problematic reference except for knowing it is somehow getting into my class-path so here is my 2 cents for lazy developers using eclipse:

Scroll down the list of maven dependencies under your project tree (usually under Java Resources -> Libraries -> Maven Dependencies), track the problematic added jar you wish to exclude from your packaged JAR, right click on it -> select Maven -> Exclude Maven Artifact ! Voila - automatically an exclusion will be added to your pom right under the dependency that refers it.

Mine BTW was 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>

Good luck!

baraka
  • 807
  • 8
  • 16
3

If you are using STS and you have added the Groovy library to your project (Project Properties -> Java Build Path -> Libraries), then make sure that you select the "No, only include groovy-all" option. The other option of "Yes, include groovy-all and bsf.jar ..., servlet-2.4.jar" adds servlet-2.4.jar which conflicts with the embedded tomcat8 classes resulting in this problem.

3

I am using Jetty in my project and got the same error. My quick solution was to exclude embedded Tomcat from the Maven dependency:

<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>
Ben
  • 1,414
  • 2
  • 13
  • 18
Olga
  • 91
  • 4
2

mvn dependency:tree did not reveal the servlet-api.jar on my classpath, but right-clicking the project (in Eclipse) and going to Build Path / Configure Build Path showed that my default workspace JRE, JDK 1.7.0_51, had that jar in its jre/lib/ext directory (at least in my installation). I tried and failed to remove it from my classpath. @Pedro's solution of forcing the tomcat version to 7 worked. So did installing the latest version of Java 7: JDK 1.7.0_79.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
whistling_marmot
  • 3,561
  • 3
  • 25
  • 39
1

I also faced this error. I have a Maven/Spring MVC/Spring Boot project. I'm using IntelliJ as the IDE and whenever i add new dependancies to the POM.xml the IDE alters the .iml file (as expected) but what's weird is that it moves the following line to the top of the file:

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

once that happens my project will not compile and I get the same error:

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

by simply moving the orderEntry for Java EE back to the bottom the error goes away and I can compile once more.

Bipin Butala
  • 165
  • 1
  • 9
0

For quick solution, I have removed the servlet-api.jar manually from the lib and than build the application and it works.Though, ideally as suggested by Kumetix, one should needs to scrutinize till the dependency which causing it to load in classpath.

road2victory
  • 486
  • 4
  • 12
0

For me this was solution;

https://mkyong.com/java/servlet-api-2-5-jar-jar-not-loaded/

adding the dependency of the servlet-api to pom.xml

  • Could have been a comment – Harsh Nov 17 '22 at 05:57
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/33185482) – Attila T Nov 19 '22 at 01:07
  • It was my first answer. I tried to copy the essentials part indeed but I need to study the format. Next time :) – Hayrullah Yasar Nov 19 '22 at 08:00