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就会更新配置。太具体的没有深入了解,这里也欢迎大佬们指点。

日志终于正常了 ( Ĭ ^ Ĭ )  完结撒花!

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