Gradle & SLF4J 拒绝排除传递依赖导致 IllegalStateException

Gradle & SLF4J refusing to exclude transitive dependencies results in IllegalStateException

我在对我的项目进行 运行 单元测试时遇到此错误:

Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting WhosebugError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
    at org.slf4j.impl.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:54)
    ... 29 more

我需要 SLF4J,但不需要以下依赖项正在设置的冲突:

dependencies {
    compile("org.springframework:spring-core:$springVersion")
    compile("org.springframework:spring-jdbc:$springVersion")
//    compile("org.springframework:spring-orm:$springVersion"
    compile("org.springframework:spring-tx:$springVersion")
    compile("org.springframework.data:spring-data-jpa:1.10.1.RELEASE") {
        exclude module: "slf4j-api"
        exclude module: "slf4j-over-slf4j"
        exclude module: "jcl-over-slf4j"
    }
    // tag::jetty[]
    compile("org.springframework.boot:spring-boot-starter-web:1.3.5.RELEASE") {
        exclude module: "spring-boot-starter-tomcat"
        exclude module: "slf4j-api"
        exclude module: "slf4j-over-slf4j"
        exclude module: "jcl-over-slf4j"
    }
    compile("org.springframework.boot:spring-boot-starter-jetty")
    // end::jetty[]
    // tag::actuator[]
    compile("org.springframework.boot:spring-boot-starter-actuator")
    // end::actuator[]
    testCompile("junit:junit")
    compile(group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Final')
    compile("org.apache.velocity:velocity:1.7")
    compile(group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21')
    compile('org.slf4j:log4j-over-slf4j:1.7.21')
    compile(group: 'org.projectlombok', name: 'lombok', version: '1.16.8')
    testCompile("org.springframework.boot:spring-boot-starter-test")
    testCompile(group: 'junit', name: 'junit', version: '4.11')
}

我可以通过以下方式停止错误:

configurations {
  all*.exclude group: "org.slf4j"

}

但是我在运行时得到 ClassNotFoundExceptions 因为需要 slf4j(及其适配器)。

有什么想法吗?我只想从 Spring 的依赖项中排除 slf4j。我已经看到很多关于这个问题的话题,但没有解决它——我的排除是否正确?

您的问题是,您有 log4j-over-slf4j - 将所有 log4j 日志记录重定向到 slf4j - slf4j-log4j12 - 将所有 slf4j 日志记录输出到 log4j - 在您的类路径中。这意味着你会有一个无限循环,这当然是错误的。

所以你必须决定你想要什么。您是否要将所有 log4j 日志记录重定向到 slf4j,然后将所有 slf4j 日志记录重定向到某个其他日志记录框架(或 slf4j-simple 例如,用于记录到 System.out 或没有绑定来抑制日志记录)或者您想将所有 slf4j 日志记录定向到 log4j,那么将 log4j 日志记录重定向到 slf4j 在第一名.

您如何正确解决问题在很大程度上取决于所需的结果。
您还可以使用 gradle 任务 dependencyInsight.

找出是什么引入了依赖项

我刚刚排除了spring-boot-starter-logging:

configurations {
    all*.exclude module: 'spring-boot-starter-logging'
}

我的依赖项现在看起来像这样:

dependencies {
    compile "org.springframework:spring-core:$springVersion"
    compile "org.springframework:spring-jdbc:$springVersion"
    compile "org.springframework:spring-orm:$springVersion"
    compile "org.springframework:spring-tx:$springVersion"
    compile "org.springframework.data:spring-data-jpa:1.10.1.RELEASE"
    compile("org.springframework.boot:spring-boot-starter-web") {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile("org.springframework.boot:spring-boot-starter-jetty")
    compile group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Final'
    compile "org.apache.velocity:velocity:1.7"
    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'
    compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.21'
    compile group: 'org.projectlombok', name: 'lombok', version: '1.16.8'
    testCompile("junit:junit")
    testCompile "org.springframework.boot:spring-boot-starter-test"
    testCompile group: 'junit', name: 'junit', version: '4.11'
}