六、spring boot 2 内嵌Tomcat 抛出异常 “Stopping service [Tomcat]”

(一)问题分析
内嵌tomcat的入口类是org.apache.catalina.core.StandardService
最终找到org.springframework.context.support.AbstractApplicationContext 定位方法refresh()

if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

debug可以正常进入,然后就看到我们希望看到的 ex了,即可根据问题进行解决

(二)根本原因解析
问题:为什么程序没有像以前一样,抛出错误信息???
分析:
Tomcat使用Commons-logging作为日志框架,而Springboot使用SLF4J作为日志框架(具体实现是Logback),但是问题是Commons-logging并没有logback的实现!
根据maven依赖,我们看到log4j和logback的包都被引入了,然后tomcat之能选择的是log4j,springboot使用的是logback。 log4j和logback只见缺少一个桥梁,正是缺少的这个桥梁,导致springboot只能输出logback!!!
中间的桥梁就是下面这个依赖:

<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
    </dependency>

这个依赖可以将log4j输出到slf4j,从而从sl4j(Logback)输出。
第一种解决方式:根据日志定位问题,然后采用加法处理,增加jcl-over-slf4j,打通slf4j和common-logs通道

第二种解决方式:解决冲突,一山不容二虎,排除掉slf4j,common-logs任意一方,spring使用slf4j,那可以排除调common-logs

从项目优化的角度看,第二种更优,可以减少不必要的依赖。

详情参见spring boot 2 内嵌Tomcat 抛出异常 “Stopping service [Tomcat]”

猜你喜欢

转载自blog.csdn.net/panchang199266/article/details/86649175