【问题标题】:Android: Duplicate class errors in proguardAndroid:proguard中的重复类错误
【发布时间】:2014-10-29 20:50:58
【问题描述】:

在编译我的应用程序时,我收到以下错误(已删除敏感的路径部分)

Execution failed for task ':app:proguardDebug'.
> java.io.IOException: Can't write [/projects/app/build/intermediates/classes-proguard/debug/classes.jar] (Can't read [/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.4/4216af16d38465bbab0f3dff8efa14204f7a399a/commons-codec-1.4.jar(;;;;;;!META-INF/MANIFEST.MF)] (Duplicate zip entry [commons-codec-1.4.jar:org/apache/commons/codec/binary/Base64.class]))

这向我表明编译器看到了应用程序尝试使用 commons.codec.binary.Base64.class 作为依赖项的两个地方。我再次检查并检查了我的库,但只有一个库(亚马逊 AWS)正在尝试使用它。

在此错误之上,我收到了一些其他警告,这些警告也为我提出了一个危险信号:

Warning:can't write resource [META-INF/LICENSE.txt] (Duplicate zip entry [commons-lang3-3.1.jar:META-INF/LICENSE.txt])
Warning:can't write resource [META-INF/NOTICE.txt] (Duplicate zip entry [commons-lang3-3.1.jar:META-INF/NOTICE.txt])
Warning:can't write resource [META-INF/LICENSE.txt] (Duplicate zip entry [commons-codec-1.4.jar:META-INF/LICENSE.txt])
Warning:can't write resource [META-INF/NOTICE.txt] (Duplicate zip entry [commons-codec-1.4.jar:META-INF/NOTICE.txt])

我根本没有在我的应用程序中明确使用 commons-codec-1.4 或 commons-lang3-3.1,以为我在后来删除它之前曾经使用过 lang3。为什么这些在编译日志中被引用?我的 Maven 库之一可以使用它们吗?我将在我的 gradle 文件中包含下面的 maven 库列表。

这是我的 proguard 和 gradle 文件供参考:

PROGUARD

-keep class org.w3c.dom.bootstrap.** { *; }
-keep class org.joda.time.** { *; }
-keep class com.facebook.** { *; }
-keep class org.apache.commons.** { *; }
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-dontwarn org.codehaus.jackson.map.ext.**
-dontwarn oauth.**
-dontwarn com.amazonaws.**
-dontwarn org.joda.time.**
-dontwarn org.apache.commons.codec.**
-dontwarn com.fasterxml.jackson.databind.ext.**

GRADLE

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion '20.0.0'

    defaultConfig {
        applicationId 'com.my.package'
        minSdkVersion 14
        targetSdkVersion 20
        versionCode 9
        versionName '1.2'
    }

    buildTypes {
        release {
            debuggable false
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
        debug {
            debuggable true
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    lintOptions {
        checkReleaseBuilds false
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/MANIFEST.MF'
    }
}

dependencies {
    compile fileTree(dir: 'libs',  include: ['*.jar'])

    //noinspection GradleDependency
    compile 'com.google.android.gms:play-services:5.0.89'

    compile 'com.nineoldandroids:library:2.4.0'
    compile 'com.viewpagerindicator:library:2.4.1@aar'
    compile 'se.emilsjolander:StickyScrollViewItems:1.1.0'
    compile 'se.emilsjolander:stickylistheaders:2.5.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.2'
    compile project(':facebook')
    compile 'com.tumblr:jumblr:0.0.10'
    compile 'com.android.support:support-v4:20.0.0'
}

我最好的猜测是这些库中的一个或多个正在使用 apache lang3 和编解码器作为它们自己的依赖项,这会在我编译应用程序时导致冲突。仅当我将 Amazon 作为必需的 jar 包含时才会出现此问题,因此我知道这在某种程度上是罪魁祸首,但我不知道还有什么与之冲突的。

我读到了一些关于在 proguard 中使用 -injars 的内容,但根据他们的文档,Android 不需要你使用它。

任何建议将不胜感激,谢谢!

【问题讨论】:

  • 如果您想了解更多有关导致这些传递依赖的原因的信息,您可以通过运行gradlew dependencyInsight --dependency=commons-lang3 询问 Gradle。
  • 我遇到了类似的问题。编译过程可以顺利完成,但我确实收到了那些与 META-INF 相关的警告
  • 我只在通用图像加载器上遇到同样的错误。运气好吗?

标签: android gradle proguard


【解决方案1】:

我不确定这是否会对您有所帮助,但我会在此处发布我的答案,以防其他人觉得这很有用。我的问题是我的依赖项声明中有 2 个引用。我使用的是 Universal Image Loader 库,我的语句如下所示:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.android.support:support-v4:22.1.1'
    compile 'uk.co.chrisjenx:calligraphy:2.0.2'
    /* UIL was the failing reference */
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
    compile 'com.google.android.gms:play-services:7.3.0'
}

我意识到这个问题(在头疼之后)是我已经通过 libs 文件夹引用了 UIL(即它已经被声明 compile fileTree(dir: 'libs', include: ['*.jar']) 编译。所以它编译一次通过libs 和一次通过显式调用来编译对 UIL 的引用。我删除了显式调用并清除了错误。也许您正在调用 libs 目录中的某些内容,该目录还包含对有问题库的引用,然后当它尝试编译 AWS 服务,它已经有一个版本的公共库和 pukes。

【讨论】:

    【解决方案2】:

    这个问题的原因是jar文件的重复。

    在您的项目目录中,尝试查找和擦除

    /projects/app/build/intermediates/classes-proguard/debug/classes.jar](无法读取[/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/ 1.4/4216af16d38465bbab0f3dff8efa14204f7a399a/commons-codec-1.4.jar

    这个 jar 文件,看看是否有任何变化。另外,如果同一目录或上层目录中有 commons-lang3-3.1.jar,请尝试将其删除并重新构建。

    希望对你有帮助!

    【讨论】:

    • 问题是当我尝试这样的事情时,在下一个 gradle 构建时它会被读取到目录中。
    • 嗯...我认为那是因为您要么指定了项目需要 jar 的地方,要么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    相关资源
    最近更新 更多