在运行 Spring MVC 应用程序时在 Spring Boot 中获取 NoSuchMethodError: javax.servlet.ServletContext.addServlet
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24080541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting NoSuchMethodError: javax.servlet.ServletContext.addServlet in Spring Boot while running a Spring MVC application
提问by Arghya Sadhu
I am getting below exception when I am trying to run a Spring MVC application using Spring boot...
当我尝试使用 Spring boot 运行 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.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
采纳答案by Emerson Farrugia
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.
foo.jar
Gradle 或 Maven 生成的胖 JAR在哪里。例如,ServletContext
可以从servlet-api
JDK 扩展目录中的旧JAR读取该类,而不是您的 Maven 或 Gradle 依赖项。
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!/]
回答by amuniz
I solved it excluding a transitive servlet-api dependency.
我解决了它,不包括可传递的 servlet-api 依赖项。
In my case, it was com.github.isrsal:spring-mvc-logger
就我而言,它是 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>
回答by kumetix
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
我的 lib jar 中有一个类似的问题,由于某种原因,它带来了一个旧版本的 javax.servlet.ServletContext,它后来由我的 spring-boot 模块而不是它自己提供的类加载,从而导致 NoSuchMethodError
I fixed it by editing the build.gradle of my lib module :
我通过编辑 lib 模块的 build.gradle 修复了它:
configurations {
provided.all*.exclude group: 'javax.servlet'
}
回答by kkonrad
I was using Gradle and what worked for me:
我正在使用 Gradle,什么对我有用:
configurations {
all*.exclude group: '', module: 'servlet-api'
}
It trimmed dependency tree in desired way.
它以所需的方式修剪依赖树。
回答by Shoham
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:
我在 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
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
回答by Pedro Hoehl Carvalho
For anyone else who couldn't solve it by excluding servlet-api
, here is an alternative:
对于无法通过 exclude 解决它的其他人servlet-api
,这里有一个替代方案:
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:
事实证明,Spring Boot 默认为 Tomcat 8。如果您运行的是不同版本的 Tomcat 并想修复此错误,只需将您的 tomcat 版本添加到 pom 属性:
<properties>
<tomcat.version>7.0.63</tomcat.version>
</properties>
回答by road2victory
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.
为了快速解决问题,我已经从库中手动删除了 servlet-api.jar,然后构建应用程序并且它可以工作。虽然,理想情况下,正如 Kumetix 所建议的那样,人们应该需要仔细检查导致它加载到类路径中的依赖项。
回答by whistling_marmot
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 Pathshowed 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 solutionof forcing the tomcat version to 7 worked. So did installing the latest version of Java 7: JDK 1.7.0_79.
mvn dependency:tree
没有servlet-api.jar
在我的类路径上显示,但右键单击项目(在 Eclipse 中)并转到构建路径/配置构建路径显示我的默认工作区 JRE,JDK 1.7.0_51,在其jre/lib/ext
目录中(至少在我的安装)。我尝试将它从我的类路径中删除,但失败了。@Pedro 将 tomcat 版本强制为 7的解决方案有效。安装最新版本的 Java 7 也是如此:JDK 1.7.0_79。
回答by Bohemian
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.
我在测试期间尝试启动我的 spring 引导服务器时遇到了这个问题(使用 gradle + spock)。我将问题追溯到wiremock 库。
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).
古老的 (2008) org.mortbay.jetty:servlet-api
jar 包含一个ServletContext
与 spring boot 1.3.2 版不兼容的版本(至少可以正常工作到 1.2.6)。
回答by ghostcoder007
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.
如果您正在使用 STS 并且您已将 Groovy 库添加到您的项目(项目属性 -> Java 构建路径 -> 库),则确保您选择了“不,仅包含 groovy-all”选项。“是的,包括 groovy-all 和 bsf.jar ..., servlet-2.4.jar”的另一个选项添加了 servlet-2.4.jar,它与导致此问题的嵌入式 tomcat8 类冲突。