Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar 解決方法

Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar 解決方法

 

問題:

導入spark依賴包後,local模式下運行spark本地程序報錯:

Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path,

preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.

這個錯運行spark程序比較常見,由於很多maven項目中都依賴了log4j的包,這裏需要針對衝突的包執行exclude即可

 

第一層(exclusion 報錯jar 包的log4j即可):

網上最常見的解決方法,也是報錯日誌官方給出的解決方案

假設我加入了spark core的依賴包:

        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.2.1</version>
        </dependency>

增加exclusion去掉上述依賴衝突的包

        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

 

第二層(org.4j版本不一致問題):

這裏需要查看maven依賴樹,找到高版本,手動添加到依賴中 https://mvnrepository.com/artifact/log4j/log4j

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.x.x</version>
</dependency>

根據maven樹的最高版本手動加入pom即可,maven樹獲取可以參考上一篇博文~

 

第三層(報錯在底層代碼庫):

第一層的情況是顯示的,即拋出的異常中包含了jar衝突的maven依賴,直接去除即可。但也有一些底層的jar包,我遇到的情況是hadoop client 和 hadoop mapreduce庫中的log4j衝突,而hadoop包並不是我自己pom引入,這個時候需要自己引入hadoop client包並exclusion掉log包

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.google.protobuf</groupId>
                    <artifactId>protobuf-java</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

 

第四層(很坑):

經歷前三種情況之一後,發現我本地的log顯示有問題,雖然spark程序運行正常,但是新增了很多spark底層日誌,懷疑是自己exclusion掉log4j的原因。

首先想到的就是通過設置spark level級別,徹底去除spark日誌

    Logger.getLogger("org").setLevel(Level.OFF)

本來以爲問題搞定,結果又報錯:

value setLevel is not a member of org.apache,log4j.logger

這裏提示沒有setLevel函數的api接口,但是正常是不會出現這個狀況,所以應該是自己exclusion過程或者版本升級過程中出現問題。

解決方法:

將log4j/properties文件放入resource中執行maven install,上述函數setLevel方法恢復正常,日誌系統顯示正常。

這裏簡單查了下應該是不配置的情況下會默認讀取spark core依賴中的log4.properties.samples,當我在項目resource中覆蓋後,log4j就會更新配置。太具體的沒有深入瞭解,這裏也歡迎大佬們指點。

日誌終於正常了 ( Ĭ ^ Ĭ )  完結撒花!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章