我有一个使用slf4j + logback的Android应用程序。 Gradle 文件如下所示:
...
compile('com.github.tony19:logback-android-core:1.1.1-6') {
exclude group: 'ch.qos.logback.core.net'
}
compile('com.github.tony19:logback-android-classic:1.1.1-6') {
exclude group: 'ch.qos.logback.core.net'
}
compile 'org.slf4j:slf4j-api:1.7.25'
我有回退.xml在资产/.当我按预期运行应用程序日志记录工作时。最近我决定添加新的单元测试(常规,而不是 android 单元测试(,但我看到没有显示日志消息。
我已将以下内容添加到 gragle 文件中:
testCompile('ch.qos.logback:logback-classic:1.2.3') {
exclude group: 'com.github.tony19'
}
现在显示日志消息,但在每次运行单元测试时,我都会收到此警告:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/o/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.3/7c4f3c474fb2c041d8028740440937705ebb473a/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/o/.gradle/caches/modules-2/files-2.1/com.github.tony19/logback-android-classic/1.1.1-6/614c66c9ece69eef48c65a8558de4fd7266d9f69/logback-android-classic-1.1.1-6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
有没有办法专门指定哪个 slf4j 绑定用于常规应用程序运行,哪些仅用于单元测试(或任何其他解决方案(?
依赖关系图:
compile - Classpath for compiling the main sources.
+--- com.bolyartech.forge.android:forge-android:7.1.0
| +--- com.bolyartech.forge:base:5.1.0
| | +--- org.slf4j:slf4j-api:1.7.7 -> 1.7.25
| | +--- com.darwinsys:hirondelle-date4j:1.5.1
| | +--- com.google.guava:guava:20.0
| | +--- javax.inject:javax.inject:1
| | --- com.squareup.okhttp3:okhttp:3.1.2
| | --- com.squareup.okio:okio:1.6.0
| +--- com.google.dagger:dagger:2.9
| | --- javax.inject:javax.inject:1
| +--- com.android.support:support-annotations:25.3.1 -> 26.0.1
| +--- javax.annotation:jsr250-api:1.0
| +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
| --- net.sourceforge.streamsupport:streamsupport:1.5.1
+--- com.bolyartech.scram_sasl:scram_sasl:2.0.1
+--- com.android.support:multidex:1.0.1
+--- com.squareup:otto:1.3.8
+--- com.google.code.gson:gson:2.7
+--- com.github.franmontiel:PersistentCookieJar:v0.9.3
| --- com.squareup.okhttp3:okhttp:3.1.2 (*)
+--- com.github.tony19:logback-android-core:1.1.1-6
+--- com.github.tony19:logback-android-classic:1.1.1-6
| +--- com.github.tony19:logback-android-core:1.1.1-6
| --- com.github.tony19:apktool-lib:1.4.4-3
| --- com.google.android:android:2.1_r1
| +--- commons-logging:commons-logging:1.1.1
| +--- org.apache.httpcomponents:httpclient:4.0.1
| | +--- org.apache.httpcomponents:httpcore:4.0.1
| | +--- commons-logging:commons-logging:1.1.1
| | --- commons-codec:commons-codec:1.3
| +--- org.khronos:opengl-api:gl1.1-android-2.1_r1
| +--- xerces:xmlParserAPIs:2.6.2
| --- xpp3:xpp3:1.1.4c
+--- ch.acra:acra:4.7.0
| --- com.android.support:support-v4:23.0.1 -> 26.0.1
| +--- com.android.support:support-compat:26.0.1
| | --- com.android.support:support-annotations:26.0.1
| +--- com.android.support:support-media-compat:26.0.1
| | +--- com.android.support:support-annotations:26.0.1
| | --- com.android.support:support-compat:26.0.1 (*)
| +--- com.android.support:support-core-utils:26.0.1
| | +--- com.android.support:support-annotations:26.0.1
| | --- com.android.support:support-compat:26.0.1 (*)
| +--- com.android.support:support-core-ui:26.0.1
| | +--- com.android.support:support-annotations:26.0.1
| | --- com.android.support:support-compat:26.0.1 (*)
| --- com.android.support:support-fragment:26.0.1
| +--- com.android.support:support-compat:26.0.1 (*)
| +--- com.android.support:support-core-ui:26.0.1 (*)
| --- com.android.support:support-core-utils:26.0.1 (*)
+--- org.slf4j:slf4j-api:1.7.25
+--- javax.inject:javax.inject:1
+--- javax.annotation:jsr250-api:1.0
+--- com.google.dagger:dagger:2.9 (*)
--- com.android.support:appcompat-v7:26.0.1
+--- com.android.support:support-annotations:26.0.1
+--- com.android.support:support-v4:26.0.1 (*)
+--- com.android.support:support-vector-drawable:26.0.1
| +--- com.android.support:support-annotations:26.0.1
| --- com.android.support:support-compat:26.0.1 (*)
--- com.android.support:animated-vector-drawable:26.0.1
+--- com.android.support:support-vector-drawable:26.0.1 (*)
--- com.android.support:support-core-ui:26.0.1 (*)
testCompile - Classpath for compiling the test sources.
+--- ch.qos.logback:logback-classic:1.2.3
| +--- ch.qos.logback:logback-core:1.2.3
| --- org.slf4j:slf4j-api:1.7.25
+--- junit:junit:4.12
| --- org.hamcrest:hamcrest-core:1.3
--- org.mockito:mockito-core:1.10.19
+--- org.hamcrest:hamcrest-core:1.1 -> 1.3
--- org.objenesis:objenesis:2.1
对于 Android Gradle 插件 3 及更高版本,请尝试使用以下版本:
implementation 'org.slf4j:slf4j-api:1.7.25'
runtimeOnly 'com.github.tony19:logback-android-core:1.1.1-6'
依赖范围
在旧版本的 gradle 中,编译的依赖范围将包含在项目的所有类路径中,即包括编译、运行时、测试编译和测试执行。因此,SLF4J类的两个实现将包含在测试执行中。
SLF4J 绑定
而且因为实现SLF4J绑定,两个绑定会导致一个警告,SLF4J会随机选择一个绑定,在这种情况下,不会回退。
溶液
因此,解决此问题的唯一方法是从测试类路径中排除 logback-android。
在新版 Gradle (4.0.2( 中,我们在runtimeElements
中定义了 logback-android,以避免被测试环境使用。在旧版本中,我们似乎无法使用 gradle 解决这个问题。
裁判
- Java 库插件
- 爪哇插件
您需要在根级别排除它,而不是 logback 经典依赖项:
configurations {
testCompile.exclude group: 'com.github.tony19'
}
使用 从测试类路径中排除 tony19 库
configurations {
testImplementation.exclude group: 'com.github.tony19'
//with testCompile the library is not used for compilation but used for running tests
}
dependencies {
//logging
implementation 'org.slf4j:slf4j-api:1.7.30'
runtimeOnly 'com.github.tony19:logback-android:2.0.0'
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.11'
}
使用testCompile.exclude
仍然发出警告
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/raiser/.gradle/caches/transforms-3/5db974f19df3b652be1c75410514efb8/transformed/jetified-logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/raiser/.gradle/caches/transforms-3/f97ca29862548c3aa25d47e0ab6abbab/transformed/jetified-logback-android-2.0.0-runtime.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/raiser/.gradle/caches/transforms-3/17f8528b15b95f4e98b73ee7482c4884/transformed/jetified-logback-android-2.0.0/jars/classes.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]