天天看點

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