項目開發中發現服務器上Tomcat啟動失敗
開始定位
第一步:打開tomcat日志catalina.log:
2017-07-25 17:02:43,799 [Catalina-startStop-1] ERROR org.apache.catalina.core.ContainerBase - A child container failed during start java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/yxicadmin]] 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:1122) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:819) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564) 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[Catalina].StandardHost[localhost].StandardContext[/yxicadmin]] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154) ... 6 more Caused by: java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager; at org.apache.tomcat.websocket.WsWebSocketContainer.<clinit>(WsWebSocketContainer.java:77) at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131) at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5506) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ... 6 more 2017-07-25 17:02:43,802 [main] ERROR org.apache.catalina.core.ContainerBase - A child container failed during start java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]] 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:1122) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:300) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:739) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.startup.Catalina.start(Catalina.java:689) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
找到關鍵點:java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager;
雖然不清楚是什么原因,不過很奇怪的是本地項目是能跑起來的。看了下測試機tomcat版本是7.0.56,本地是7.0.68,難道和這個有關?
第二步:判斷是否和tomcat版本有關:
下載了一個7.0.56版本的tomcat,在本地運行,果不其然,也復現了該錯誤。然而是不是和tomcat有關呢?這個不不能確定,但是有一點是可以肯定的,測試機tomcat版本替換難度較大,而且還要所有環境版本同步,這個代價較大,因此轉換思路,是否是類沖突了呢。。
開始百度
第三步:發現關鍵原因:類沖突
網上查找類似錯誤,有前輩遇到了,並且分析了原因:Springboot內嵌tomcat8,與tomcat7沖突,突然意識到這個需求引入了部門其他同事提供的Jar包,難道是那個Jar包導致的。。
OK,那我們驗證下,先使用maven命令:mvn dependency:tree 輸出下maven依賴樹:
發現關鍵點:
[INFO] +- com.xxx.xxx.xx:xxx-client:jar:1.0-SNAPSHOT:compile [INFO] | +- com.netease.mail.dp:dqs-model:jar:1.0-SNAPSHOT:compile [INFO] | +- org.apache.commons:commons-lang3:jar:3.4:compile [INFO] | +- commons-httpclient:commons-httpclient:jar:3.1:compile [INFO] | +- org.springframework.boot:spring-boot-starter-web:jar:1.5.1.RELEASE:compile [INFO] | | \- org.springframework.boot:spring-boot-starter:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile [INFO] | | \- org.springframework.boot:spring-boot-starter-logging:jar:1.5.1.RELEASE:compile
果然,這個XXXJar包引用了org.springframework.boot:spring-boot-starter-web
試着使用網上的辦法去掉spring-boot-starter-web依賴的spring-boot-starter-tomcat Jar包,沒用
於是直接粗暴點:
<dependency> <groupId>com.xxx.xxx.xxx</groupId> <artifactId>xxx-client</artifactId> <version>1.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </exclusion> <exclusion> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-el</artifactId> </exclusion> <exclusion> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-websocket</artifactId> </exclusion> </exclusions> </dependency>
重新打包運行,問題解決。