Android 如何使用gradle从maven repo中正确删除可传递依赖项

Android 如何使用gradle从maven repo中正确删除可传递依赖项,android,maven,gradle,android-studio,dependency-management,Android,Maven,Gradle,Android Studio,Dependency Management,在生成项目时,我遇到以下错误: UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexException: Multiple dex files define Lorg/slf4j/impl/StaticLoggerBinder; at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:594) at com.android.dx.

在生成项目时,我遇到以下错误:

UNEXPECTED TOP-LEVEL EXCEPTION:
    com.android.dex.DexException: Multiple dex files define Lorg/slf4j/impl/StaticLoggerBinder;
        at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:594)
        at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:552)
        at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:533)
        at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:170)
        at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)
        at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)
        at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)
        at com.android.dx.command.dexer.Main.run(Main.java:230)
        at com.android.dx.command.dexer.Main.main(Main.java:199)
        at com.android.dx.command.Main.main(Main.java:103)
据我所知,这是因为我有多个依赖于slf4j的库。my build.gradle文件中的依赖项包括:

dependencies {
    compile project(':libraries:some-sdk')
    compile files('libs/some-library.jar')
    compile 'com.some-module:some-artifact:X.X.X'
    compile 'com.github.tony19:logback-android-classic:1.1.1-3'
}
我知道logback android classic依赖性是个问题,因为它确实依赖于slf4j,如果我对此进行评论,我的项目构建会很好。根据其他来源,我发现这通常通过排除可传递依赖性来解决,如下所示:

compile('com.github.tony19:logback-android-classic:1.1.1-3') {
    exclude group: 'org.slf4j'
然而,即使在我清理和重建之后,我仍然会得到错误

更新: 按照dmahapatro的建议运行dependencyInsight查找slf4j时未返回任何结果:

$ gradle -q dependencyInsight --dependency slf4j --configuration compile
No dependencies matching given input were found in configuration ':main:compile'
我的完整依赖关系树是:

+--- project :stripe
+--- project :apptentive-android-sdk
+--- project :numberpicker
+--- project :switch-backport
+--- org.jsoup:jsoup:1.7.3
+--- org.ocpsoft.prettytime:prettytime:3.2.4.Final
+--- org.mockito:mockito-all:1.9.5
+--- com.google.dexmaker:dexmaker:1.0
+--- com.google.dexmaker:dexmaker-mockito:1.0
+--- com.pusher:pusher-java-client:0.3.1
\--- com.github.tony19:logback-android-classic:1.1.1-3
     +--- 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
     \--- com.github.tony19:logback-android-core:1.1.1-3
更新2:

我已将冲突缩小到logback android classic库和本地jar(不幸的是,由于许可问题,我无法直接编辑此jar)。排除其中任何一个都可以解决冲突,只有这两个依赖项的空通用测试应用程序将有冲突。我已经验证了本地jar包含org.slf4j,但是由于前面提到的许可问题,我对此无能为力。因此,我唯一的选择就是将slf4j从logback android classic中排除。考虑到依赖关系树实际上没有将slf4j显示为logback android classic的依赖关系,并且

    compile('com.github.tony19:logback-android-classic:1.1.1-3') {
            exclude group: 'org.slf4j'
    }
尚未解决问题,如何从logback android classic中排除slf4j依赖项

最后更新:
最终,通过与本地jar的所有者合作解决了这一问题,我正在使用该jar删除logback。我怀疑这对于未来的访问者来说是一个特别有用的答案,但为了完成,我想将其包括在内。

我在“build.gradle”中添加了以下内容,以消除“slf4j”的可传递依赖性问题。这是排除依赖项的方法,这样就不会以传递方式加载依赖项。并通过在“compilegroup”语句中提及它来显式加载冲突库。我想这可能对你有帮助

configurations {
    all*.exclude group: 'ch.qos.logback'
    all*.exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
    all*.exclude group: 'org.slf4j', module: 'jul-to-slf4j'
    all*.exclude group: 'org.slf4j', module: 'log4j-over-slf4j'
    all*.exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
    all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12'
    all*.exclude group: 'org.slf4j', module: 'slf4j-simple'
}

compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: slf4jToLog4jVersion

运行
dependencyInsight
查看从哪里拉取
slf4j
gradle-p dependencyInsight--dependency slf4j--configuration compile
。这会让事情变得清楚。我得到了“未找到名为‘compile’的配置”。我知道这通常是由于缺少build.gradle文件造成的,但我已经验证了它们都存在。有什么建议吗?否则我想这可能是它自己的问题。我的意思是
-q
,而不是
-p
。我的错
gradle-q dependencyInsight--dependency slf4j--configuration compile
。仍在获取“未找到名为“compile”的配置”。错误。这是多项目生成吗?这个应用程序可以在github中共享吗,或者至少在Gist中的build.gradle文件中共享吗?我尝试了一下,但似乎没有任何效果,仍然得到了与上面相同的错误。我可能实现错了,我假设编译语句放在依赖项块中,但不完全确定配置块会放在哪里。我已经在build.gradle的基本级别和android{}块中尝试过了。是的,编译语句将进入依赖项块,配置块将与依赖项级别在同一级别。