Gradle 库包含失败 'IllegalArgumentException: already added'

Gradle fails with 'IllegalArgumentException: already added' on library inclusion

我正在尝试在我的新的基本框架 Android Studio 项目中包含一个库。

我的模块 build.gradle 包含以下内容:

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'org.jmrtd:jmrtd:0.5.0-RELEASE'
}

Build-and-运行 在 preDexDebug-step 失败,堆栈跟踪如下:

UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Lnet/sf/scuba/data/Country;
    at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:122)
    at com.android.dx.dex.file.DexFile.add(DexFile.java:161)
    at com.android.dx.command.dexer.Main.processClass(Main.java:732)
    at com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)
    at com.android.dx.command.dexer.Main.access0(Main.java:83)
    at com.android.dx.command.dexer.Main.processFileBytes(Main.java:602)
    at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
    at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
    at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
    at com.android.dx.command.dexer.Main.processOne(Main.java:632)
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)
    at com.android.dx.command.dexer.Main.run(Main.java:246)
    at com.android.dx.command.dexer.Main.main(Main.java:215)
    at com.android.dx.command.Main.main(Main.java:106)
1 error; aborting

现在,我已经寻找了所有可能导致此问题(包含多个库)的明显问题,但似乎找不到罪魁祸首。该库仅包含一次,并且是除 Android 支持库之外的唯一依赖项。

错误的包含似乎源于 JMRTD 中的传递依赖。排除或包括此库 (scuba) 似乎没有任何区别。

我也尝试过在我的 libs 文件夹中手动添加库,但我遇到了同样的问题。

有趣的是,如果我像这样完全排除传递依赖...

configurations {
    all*.exclude group: 'net.sf.scuba', module: 'scuba-smartcards'
}

...preDexDebug 步骤在不同的文件上失败(它本身是库的一部分,不包含在依赖项中):

UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Lorg/jmrtd/BACDeniedException;
    at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:122)
    at com.android.dx.dex.file.DexFile.add(DexFile.java:161)

旁注:如果您按字母顺序查看 jar 内容,失败的文件是列出的第一个文件,表明所有 class 个文件将以相同的方式失败。

是否存在某种我不知道的内部重复?我包含的工件经检查似乎没问题,但从存储库中获取的文件格式是否存在问题?

谢谢!

免责声明:我是 Android 和 Gradle 的新手。不过,我对 Maven 和 Java 有丰富的经验。

对于那些可能遇到类似问题的人:这原来是由于两个有问题的库(jmrtd + scuba)的错误 ant 构建引起的,每个 class 文件都包含两次。这很难检测到,因为一些文件管理器不会列出存档的重复内容。

我最终通过 运行 'tar tf ' 确认发现重复项并通过使用 ant jar-task 属性自己构建库来修复它 'duplicate="preserve"'。

但总的来说,根本原因是 ant 可怕的默认行为是添加两个相同的文件而不是 failing/overwriting 加上处理重复项时 Gradle 的挑剔。