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

时间:2016-05-30 11:41:18

标签: spring gradle log4j slf4j

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

Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. 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。我在这个问题上看到了很多线索,但没有解决它 - 我的排除是否正确?

2 个答案:

答案 0 :(得分:12)

我刚刚排除了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'
}

答案 1 :(得分:2)

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

所以你必须决定你想要什么。是否要将所有log4j日志记录重定向到log4j,然后将所有slf4j日志记录定向到其他日志记录框架(或slf4j,例如用于登录slf4j-simple或没有绑定来阻止日志记录)或者您想将所有System.out日志记录定向到slf4j,那么将log4j日志记录重定向到log4j是没有意义的首先。

如何正确解决问题取决于所需的结果 您还可以使用gradle任务slf4j找出依赖项中的内容。