Spring boot项目部署linux系统tomcat报错解决办法

作者:青山常在人不老   阅读 (2297)  |  收藏 (0)  |  点赞 (0)

摘要

Spring boot 项目部署linux tomcat 报:java.io.IOException: java.lang.ClassCastException: Cannot cast ch.qos.logback.classic.servlet.LogbackServletContainerInitializer to javax.servlet.ServletContainerInitializer解决办法


原文链接:Spring boot项目部署linux系统tomcat报错解决办法

一、问题出现的场景:

一个Spring boot项目,使用log4j打印日志,在windows tomcat中部署正常启动,但是在linux系统中部署到tomcat 中时报了如下的错误:

java.io.IOException: java.lang.ClassCastException: Cannot cast ch.qos.logback.classic.servlet.LogbackServletContainerInitializer to javax.servlet.ServletContainerInitializer
	at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:185)
	at org.apache.catalina.startup.WebappServiceLoader.load(WebappServiceLoader.java:151)
	at org.apache.catalina.startup.ContextConfig.processServletContainerInitializers(ContextConfig.java:1597)
	at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1125)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:768)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:303)
	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:5058)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:697)
	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1134)
	at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1780)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassCastException: Cannot cast ch.qos.logback.classic.servlet.LogbackServletContainerInitializer to javax.servlet.ServletContainerInitializer
	at java.lang.Class.cast(Class.java:3369)
	at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:182)
	... 19 more

二、寻求解决问题的道路

看报错提示很明显,一开始以为是jar引入冲突造成的,可以分析了Pom.xml文件和application.properties文件发现,并没有明显的引入jar和配置错误啊,甚至我都没引入log4j的依赖(Spring boot框架默认继承的父类pom.xml中已经引入了相关的依赖,如下图)

java.io.IOException: java.lang.ClassCastException: Cannot cast ch.qos.logback.classic.servlet.LogbackServletContainerInitializer to javax.servlet.ServletContainerInitializer解决办法

那么这就奇怪了,明明父类中已经引入了logging依赖,为啥还会强行转换为 javax.servlet.ServletContainerInitializer呢?

首先想到的是度娘,搜索了很久,很失望的发现,根本没有能帮助我解决问题的文章啊,于是去google上搜索该问题,找到了一篇文章,说linux下tomcat 运行 maven项目时加载的jar有一个优先级,可能会把apach-tomcat下lib下的jar先加载上,于是我去搜索如何修改tomcat加载jar优先级的方法,感觉绝望的是,只是找到了一些关于tomcat加载jar优先级的文章:tomcat中加载class和jar优先级,但是却没有如何修改这个优先级的文章;感觉自己找错了方向,于是再次回去翻阅google上查到的文章,再次会想起上文报的错误,忽然想到,能不能在pom.xml中直接屏蔽下面的这个类呢?

javax.servlet.ServletContainerInitializer

于是我尝试在pom.xml的下面位置加上了一段代码:

Cannot cast ch.qos.logback.classic.servlet.LogbackServletContainerInitializer to javax.servlet.ServletContainerInitializer解决办法

以屏蔽打包时打入servlet.api.jar

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <!-- 编译测试期间有效 -->
   <scope>provided</scope>
</dependency>

clearn 后再次install打包,部署,OK,终于成功。


分类   Spring boot 开发
字数   3025

博客标签    spring boot错误   linux 部署Spring boot报错  

评论