天天看点

六、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