![](/img/trans.png)
[英]Unable to start embedded container; nested exception is java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet
[英]Getting NoSuchMethodError: javax.servlet.ServletContext.addServlet in Spring Boot while running a Spring MVC application
當我嘗試使用 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
如果你想找出加載類的位置,試試吧
java -verbose:class -jar foo.jar | grep javax.servlet.ServletContext
其中foo.jar
是Gradle或Maven生產的胖JAR。 例如,可以從JDK擴展目錄中的舊servlet-api
JAR而不是Maven或Gradle依賴項中讀取ServletContext
類。
命令的輸出看起來像這樣......
$ 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!/]
我解決了它,不包括傳遞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>
gradle解決方案。
我在我的lib jar中遇到了類似的問題,由於某種原因,它帶來了舊版本的javax.servlet.ServletContext,后來由我的spring-boot模塊而不是它自己提供的類加載,導致NoSuchMethodError
我通過編輯我的lib模塊的build.gradle來修復它:
configurations {
provided.all*.exclude group: 'javax.servlet'
}
對於其他任何無法通過排除servlet-api
來解決它的人,這里有一個替代方案:
事實證明Spring Boot默認為Tomcat 8.如果您運行的是不同版本的Tomcat並想修復此錯誤,只需將您的tomcat版本添加到pom屬性:
<properties>
<tomcat.version>7.0.63</tomcat.version>
</properties>
我在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
我在測試期間嘗試啟動彈簧啟動服務器時遇到此問題(使用gradle + spock)。 我將問題追溯到了線索庫。
這解決了它:
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
,它與Spring引導版本1.3.2不兼容(工作正常至少高達1.2.6)。
我在使用Gradle以及對我有用的東西:
configurations {
all*.exclude group: '', module: 'servlet-api'
}
它以期望的方式修剪了依賴樹。
我使用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>
根據這個解決方案: https : //stevewall123.wordpress.com/2015/04/17/spring-boot-application-and-tomcat-error-a-child-container-failed-during-start/
您可以通過設置“tomcat.version”屬性來更改Tomcat版本:
ext['tomcat.version'] = '7.0.63' //my version of Tomcat
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
}
由於該文章的作者,它對我有用。
干杯:)
如果您正在使用STS並且已將Groovy庫添加到項目中(項目屬性 - > Java構建路徑 - >庫),請確保選擇“否,僅包括groovy-all”選項。 “是,包括groovy-all和bsf.jar ...,servlet-2.4.jar”的另一個選項添加了servlet-2.4.jar,它與嵌入式tomcat8類沖突導致了這個問題。
我在我的項目中使用Jetty並得到了同樣的錯誤。 我的快速解決方案是從Maven依賴項中排除嵌入式Tomcat:
<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>
我無法追蹤有問題的引用,除非知道它以某種方式進入我的類路徑所以這是我使用eclipse的懶惰開發人員的2美分:
向下滾動項目樹下的maven依賴項列表(通常在Java Resources - > Libraries - > Maven Dependencies下),跟蹤要從打包的JAR中排除的有問題的jar,右鍵單擊它 - >選擇Maven - > Exclude Maven神器! 瞧 - 自動排除將被添加到您的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>
祝好運!
mvn dependency:tree
沒有在我的類路徑中顯示servlet-api.jar
,但右鍵單擊項目(在Eclipse中)並轉到Build Path / Configure Build Path顯示我的默認工作區JRE,JDK 1.7.0_51,有jar的jre/lib/ext
目錄(至少在我的安裝中)。 我試過並且沒能將它從我的類路徑中刪除。 @ Pedro強制將tomcat版本改為7的解決方案 。 所以安裝最新版本的Java 7:JDK 1.7.0_79。
我也遇到了這個錯誤。 我有一個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 for Java EE移回底部,錯誤消失了,我可以再次編譯。
為了快速解決,我已經從lib中手動刪除了servlet-api.jar,而不是構建應用程序並且它可以工作。盡管如此,理想情況下,如Kumetix所建議的,應該仔細檢查直到導致它在類路徑中加載的依賴關系。
對我來說,這是解決方案;
https://mkyong.com/java/servlet-api-2-5-jar-jar-not-loaded/
將 servlet-api 的依賴添加到 pom.xml
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.