在运行Spring MVC应用程序时获取NoSuchMethodError:Spring Boot中的javax.servlet.ServletContext.addServlet

Arg*_*dhu 38 java spring-mvc nosuchmethoderror spring-boot lifecycleexception

当我尝试使用Spring启动运行Spring MVC应用程序时,我遇到了异常...

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
Run Code Online (Sandbox Code Playgroud)

Eme*_*gia 27

如果你想找出加载类的位置,试试吧

java -verbose:class -jar foo.jar | grep javax.servlet.ServletContext
Run Code Online (Sandbox Code Playgroud)

foo.jarGradle或Maven生产的脂肪JAR 在哪里?例如,ServletContext可以从servlet-apiJDK扩展目录中的旧JAR而不是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!/]
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢这个答案,因为它让你了解问题的根源.所有其他的都是"我也是这样,我解决了......".因此,如果由于不同的原因导致相同的问题,则无法使用其他答案进行故障排除.这是最有用的全能答案. (3认同)

amu*_*niz 25

我解决了它,不包括传递servlet-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>
Run Code Online (Sandbox Code Playgroud)


kum*_*tix 22

gradle解决方案.

我在我的lib jar中遇到了类似的问题,由于某种原因,它带来了旧版本的javax.servlet.ServletContext,后来由我的spring-boot模块而不是它自己提供的类加载,导致NoSuchMethodError

我通过编辑我的lib模块的build.gradle来修复它:

configurations {
    provided.all*.exclude group: 'javax.servlet'
}
Run Code Online (Sandbox Code Playgroud)


Ped*_*lho 7

对于其他通过排除无法解决问题的人servlet-api,这里有一个替代方案:

事实证明Spring Boot默认为Tomcat 8.如果您运行的是不同版本的Tomcat并想修复此错误,只需将您的tomcat版本添加到pom属性:

<properties>
    <tomcat.version>7.0.63</tomcat.version>
</properties> 
Run Code Online (Sandbox Code Playgroud)


Sho*_*ham 6

我在spring-boot webapp中有这个,只在部署服务器中(在我的本地机器上正常运行).我通过添加:

<dependencies>
<!-- … -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<!-- … -->
Run Code Online (Sandbox Code Playgroud)

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


Boh*_*ian 6

我在测试期间尝试启动弹簧启动服务器时遇到此问题(使用gradle + spock).我将问题追溯到了线索库.

这解决了它:

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

FYI

gradle dependencies
Run Code Online (Sandbox Code Playgroud)

节目(删节):

\--- 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
Run Code Online (Sandbox Code Playgroud)

古代(2008)org.mortbay.jetty:servlet-apijar包含的版本ServletContext与弹簧启动版本1.3.2不兼容(工作正常至少高达1.2.6).


kko*_*rad 5

我在使用Gradle以及对我有用的东西:

configurations {
    all*.exclude group: '', module: 'servlet-api'
}
Run Code Online (Sandbox Code Playgroud)

它以期望的方式修剪了依赖树.


Pra*_*K S 5

我使用Spring-boot运行Hadoop 2.7.2,以下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>
Run Code Online (Sandbox Code Playgroud)