Spring Boot项目,Tomcat启动过程中报错:
org.apache.catalina.LifecycleException: Failed to start component
如果报错信息中包含
java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String
这是因为在pom.xml文件中引入了 servlet-api 依赖或者在 spring-boot-web-starter 包中包含了 servlet-api 包,而Tomcat自带的也有 servlet-api 的jar包,
Tomcat启动时会加载其中某个 servlet-api.jar 包,而包中没有 getVirtualServerName() 方法, 但是该包只会加载一次,之后不会再去加载另一个jar包,故而造成加载方法失败,tomcat就会关闭。
本人经过测试,发现当删除tomcat下的 servlet-api.jar 时,启动依然报错,而删除 maven 下的 servlet-api.jar 时,项目可以正常启动,所以判断:
1、maven和tomcat下都有 servlet-api.jar 包,其中 tomcat 下的 servlet-api.jar 包是正常的,而 maven 下的 servlet-api.jar 是不包含 getVirtualServerName() 方法的;
2、tomcat启动时会先加载maven中的 servlet-api.jar 包而不是自己文件夹下的 servlet-api.jar 包,这点和其他文章中所说的有差异。
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122) [na:1.8.0_181]
at java.util.concurrent.FutureTask.get(FutureTask.java:192) [na:1.8.0_181]
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:942) ~[tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:872) [tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1423) [tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1413) [tomcat-embed-core-8.5.35.jar:8.5.35]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.35.jar:8.5.35]
... 6 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [Pipeline[StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5166) ~[tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.35.jar:8.5.35]
... 6 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.authenticator.NonLoginAuthenticator[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:182) ~[tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.35.jar:8.5.35]
... 8 common frames omitted
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
at org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1181) ~[tomcat-embed-core-8.5.35.jar:8.5.35]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.35.jar:8.5.35]
... 10 common frames omitted
解决方法:
1、在pom文件中加入以下依赖,provided仅仅需要在编译和测试阶段,provide将不会被打包到lib目录下,所以启动时使用的是tomcat中的servlet-api.jar 包。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
2、直接删除本地maven仓库中的 servlet-api.jar 包,解决冲突。