Groovy @Slf4j 注释:"Class path contains multiple SLF4J bindings"
Groovy @Slf4j annotation: "Class path contains multiple SLF4J bindings"
关于这个主题有几个问题,但我能找到的 none 与 Groovy @Slf4j
"AST" 注释有关。从表面上看,这不仅方便,而且可以根据日志级别有条件地执行内容。
在我的书中,Groovy在行动中,它说:
Injects an Slf4j logger as a static final org.slf4j.Logger into your
class and initializes it using
org.slf4j.LoggerFactory.getLogger(class) . The LogBack framework uses
SLF4J as the underlying logger, so LogBack users should use @Slf4j
这就是我正在做的。我的 gradle.build
里有这个
compile 'ch.qos.logback:logback-classic:1.2.1'
...我已经搞定了一个简单的 logback-test.xml.
但每次我 运行 使用此注释测试 class 或直接 运行 应用程序时,我都会得到:
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found
binding in [jar:file:/D:/apps/...
fbb0e/logback-classic-1.2.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/apps/...
eca4e/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an
explanation.
SLF4J: Actual binding is of type
[ch.qos.logback.classic.util.ContextSelectorStaticBinder]
...特别是,这是我的 "polluting" 我的 stderr
测试输出。
我尝试手动删除 slf4j-log4j12-1.7.6.jar 文件...但它会在下一个 Gradle 任务中自动重新生成。
Jon Skeet是本书的作者之一。是的,THE 乔恩双向飞碟。帮助乔恩!
回复两条评论(谢谢!)
...这是输出
+--- org.codehaus.groovy:groovy-all:2.6.0-alpha-2
+--- net.bytebuddy:byte-buddy:1.6.11
+--- commons-io:commons-io:2.6
+--- org.apache.odftoolkit:simple-odf:0.8.2-incubating
| +--- org.apache.odftoolkit:odfdom-java:0.8.11-incubating
| | +--- org.apache.odftoolkit:taglets:0.8.11-incubating
| | +--- xerces:xercesImpl:2.9.1 -> 2.11.0
| | | \--- xml-apis:xml-apis:1.4.01
| | +--- xml-apis:xml-apis:1.3.04 -> 1.4.01
| | +--- org.apache.jena:jena-core:2.11.2
| | | +--- org.slf4j:slf4j-api:1.7.6 -> 1.7.22
| | | +--- org.apache.jena:jena-iri:1.0.2
| | | | +--- org.slf4j:slf4j-api:1.7.6 -> 1.7.22
| | | | \--- log4j:log4j:1.2.17
| | | +--- xerces:xercesImpl:2.11.0 (*)
| | | \--- log4j:log4j:1.2.17
| | +--- net.rootdev:java-rdfa:0.4.2
| | | +--- org.apache.jena:jena-iri:0.9.1 -> 1.0.2 (*)
| | | \--- org.slf4j:slf4j-api:1.5.6 -> 1.7.22
| | \--- commons-validator:commons-validator:1.5.0
| | +--- commons-beanutils:commons-beanutils:1.9.2
| | | +--- commons-logging:commons-logging:1.1.1 -> 1.2
| | | \--- commons-collections:commons-collections:3.2.1 -> 3.2.2
| | +--- commons-digester:commons-digester:1.8.1
| | +--- commons-logging:commons-logging:1.2
| | \--- commons-collections:commons-collections:3.2.2
| +--- xerces:xercesImpl:2.9.1 -> 2.11.0 (*)
| \--- xml-apis:xml-apis:1.3.04 -> 1.4.01
+--- org.apache.lucene:lucene-core:6.+ -> 6.6.2
+--- org.apache.lucene:lucene-analyzers-common:6.+ -> 6.6.2
| \--- org.apache.lucene:lucene-core:6.6.2
+--- org.apache.lucene:lucene-queryparser:6.+ -> 6.6.2
| +--- org.apache.lucene:lucene-core:6.6.2
| +--- org.apache.lucene:lucene-queries:6.6.2
| \--- org.apache.lucene:lucene-sandbox:6.6.2
+--- commons-io:commons-io:2.5 -> 2.6
\--- ch.qos.logback:logback-classic:1.2.1
+--- ch.qos.logback:logback-core:1.2.1
\--- org.slf4j:slf4j-api:1.7.22
显然,Szymon Stepniak 的评论是正确的。现在我只需要找出如何排除罪魁祸首 (odftoolkit) 包对 log4j 的这种使用... here 我发现有人想这样做。
您在控制台中看到的这条错误消息实际上与代码中使用的 @Slf4j
注释无关 - 它只是简化了向 class 添加 log
字段的过程。您的问题是由 class 路径中的多个 org.slf4j.impl.StaticLoggerBinder
class 引起的。要修复它,您必须首先使用以下方法检查依赖关系树:
gradle dependencies --configuration runtime
它将显示所有依赖项的完整树。比您可以追踪哪个依赖项正在向您的 class 路径添加额外的记录器。正如您在评论中提到的,在您的情况下是 org.apache.odftoolkit:simple-odf:0.8.2-incubating
添加 log4j
依赖项。
知道你必须排除组 org.slf4j
和 log4j
随 org.apache.odftoolkit:simple-odf:0.8.2-incubating
而来的传递依赖。在您的 build.gradle
文件中定义此依赖项,如下所示:
compile ("org.apache.odftoolkit:simple-odf:0.8.2-incubating") {
exclude group: 'org.slf4j'
exclude group: 'log4j'
}
出于兴趣,尽管 Szymon Stepniak 的解决方案可能是最好的解决方案,但还有另一种解决方案,我基本上是从 this question:
获得的
configurations {
runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}
...我想这可能有一个优点,即您不必单独处理每个有问题的包的排除...?
关于这个主题有几个问题,但我能找到的 none 与 Groovy @Slf4j
"AST" 注释有关。从表面上看,这不仅方便,而且可以根据日志级别有条件地执行内容。
在我的书中,Groovy在行动中,它说:
Injects an Slf4j logger as a static final org.slf4j.Logger into your class and initializes it using org.slf4j.LoggerFactory.getLogger(class) . The LogBack framework uses SLF4J as the underlying logger, so LogBack users should use @Slf4j
这就是我正在做的。我的 gradle.build
里有这个compile 'ch.qos.logback:logback-classic:1.2.1'
...我已经搞定了一个简单的 logback-test.xml.
但每次我 运行 使用此注释测试 class 或直接 运行 应用程序时,我都会得到:
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/apps/... fbb0e/logback-classic-1.2.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/apps/... eca4e/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
...特别是,这是我的 "polluting" 我的 stderr
测试输出。
我尝试手动删除 slf4j-log4j12-1.7.6.jar 文件...但它会在下一个 Gradle 任务中自动重新生成。
Jon Skeet是本书的作者之一。是的,THE 乔恩双向飞碟。帮助乔恩!
回复两条评论(谢谢!)
...这是输出
+--- org.codehaus.groovy:groovy-all:2.6.0-alpha-2
+--- net.bytebuddy:byte-buddy:1.6.11
+--- commons-io:commons-io:2.6
+--- org.apache.odftoolkit:simple-odf:0.8.2-incubating
| +--- org.apache.odftoolkit:odfdom-java:0.8.11-incubating
| | +--- org.apache.odftoolkit:taglets:0.8.11-incubating
| | +--- xerces:xercesImpl:2.9.1 -> 2.11.0
| | | \--- xml-apis:xml-apis:1.4.01
| | +--- xml-apis:xml-apis:1.3.04 -> 1.4.01
| | +--- org.apache.jena:jena-core:2.11.2
| | | +--- org.slf4j:slf4j-api:1.7.6 -> 1.7.22
| | | +--- org.apache.jena:jena-iri:1.0.2
| | | | +--- org.slf4j:slf4j-api:1.7.6 -> 1.7.22
| | | | \--- log4j:log4j:1.2.17
| | | +--- xerces:xercesImpl:2.11.0 (*)
| | | \--- log4j:log4j:1.2.17
| | +--- net.rootdev:java-rdfa:0.4.2
| | | +--- org.apache.jena:jena-iri:0.9.1 -> 1.0.2 (*)
| | | \--- org.slf4j:slf4j-api:1.5.6 -> 1.7.22
| | \--- commons-validator:commons-validator:1.5.0
| | +--- commons-beanutils:commons-beanutils:1.9.2
| | | +--- commons-logging:commons-logging:1.1.1 -> 1.2
| | | \--- commons-collections:commons-collections:3.2.1 -> 3.2.2
| | +--- commons-digester:commons-digester:1.8.1
| | +--- commons-logging:commons-logging:1.2
| | \--- commons-collections:commons-collections:3.2.2
| +--- xerces:xercesImpl:2.9.1 -> 2.11.0 (*)
| \--- xml-apis:xml-apis:1.3.04 -> 1.4.01
+--- org.apache.lucene:lucene-core:6.+ -> 6.6.2
+--- org.apache.lucene:lucene-analyzers-common:6.+ -> 6.6.2
| \--- org.apache.lucene:lucene-core:6.6.2
+--- org.apache.lucene:lucene-queryparser:6.+ -> 6.6.2
| +--- org.apache.lucene:lucene-core:6.6.2
| +--- org.apache.lucene:lucene-queries:6.6.2
| \--- org.apache.lucene:lucene-sandbox:6.6.2
+--- commons-io:commons-io:2.5 -> 2.6
\--- ch.qos.logback:logback-classic:1.2.1
+--- ch.qos.logback:logback-core:1.2.1
\--- org.slf4j:slf4j-api:1.7.22
显然,Szymon Stepniak 的评论是正确的。现在我只需要找出如何排除罪魁祸首 (odftoolkit) 包对 log4j 的这种使用... here 我发现有人想这样做。
您在控制台中看到的这条错误消息实际上与代码中使用的 @Slf4j
注释无关 - 它只是简化了向 class 添加 log
字段的过程。您的问题是由 class 路径中的多个 org.slf4j.impl.StaticLoggerBinder
class 引起的。要修复它,您必须首先使用以下方法检查依赖关系树:
gradle dependencies --configuration runtime
它将显示所有依赖项的完整树。比您可以追踪哪个依赖项正在向您的 class 路径添加额外的记录器。正如您在评论中提到的,在您的情况下是 org.apache.odftoolkit:simple-odf:0.8.2-incubating
添加 log4j
依赖项。
知道你必须排除组 org.slf4j
和 log4j
随 org.apache.odftoolkit:simple-odf:0.8.2-incubating
而来的传递依赖。在您的 build.gradle
文件中定义此依赖项,如下所示:
compile ("org.apache.odftoolkit:simple-odf:0.8.2-incubating") {
exclude group: 'org.slf4j'
exclude group: 'log4j'
}
出于兴趣,尽管 Szymon Stepniak 的解决方案可能是最好的解决方案,但还有另一种解决方案,我基本上是从 this question:
获得的configurations {
runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}
...我想这可能有一个优点,即您不必单独处理每个有问题的包的排除...?