Junit无法使用java.lang.LinkageError重复的类定义为log4j类运行名称

问题描述

当我运行单元测试时,我从构建的测试运行阶段就抱怨类路径中存在重复的类。我最近没有更改我的依赖关系,所以这令人惊讶。

[junit]线程“ Thread-4”中的异常java.lang.LinkageError:加载程序 (org / powermock / core / classloader / MockClassLoader的实例): 尝试为名称重复类定义: “ org / apache / log4j / pattern / Log4j1MdcPatternConverter”

例如,当我尝试使用@PowerMockIgnore批注来排除该模式时,所涉及的类就会更改:

@PowerMockIgnore({"org.apache.log4j.pattern.Log4j1MdcPatternConverter"})

它只是抱怨另一个重复的类,例如Log4j1XmlLayout或Log4j1NdcPatternConverter。我可能可以蛮力排除哪些对象,但是在谁知道要使用排除模式之前,有没有人见过这个问题?我使用的格式类似于this question about LinkageErrors in unit tests,但用于不同的类。

其他一些问题和答案提到,他们使用log4j和其他Apache相关软件包更改了其依存关系的顺序;在这种情况下,由于无法在构建环境中控制它们(我无法在Maven或Gradle中进行任何更改),因此无法更改依赖项的加载顺序。我正在寻找最小的变化,那应该只是在失败的测试类的顶部放置一个PowerMockIgnore注释。

解决方法

经过大量的暴力测试之后,这种模式才能使测试运行而不会出现重复的班级投诉(将此放在您班级的顶部)

@PowerMockIgnore({
    "org.apache.log4j.pattern.Log4j1MdcPatternConverter","org.apache.log4j.pattern.Log4j1NdcPatternConverter","org.apache.log4j.layout.Log4j1XmlLayout","org.apache.logging.log4j.*","org.apache.logging.log4j.core.*"
})

请注意必须排除的各个类(没有通配符)才能加载并运行。