halvdanhg
halvdanhg

Reputation: 198

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

I'm trying to include a library in my new, bare bones Android Studio project.

My module's build.gradle contains the following:

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-run fails at the preDexDebug-step with the following stacktrace:

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.access$300(Main.java:83)
    at com.android.dx.command.dexer.Main$1.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

Now, I've looked for all the obvious problems which could cause this (multiple library inclusion) but can't seem to find the culprit. The library is included only once, and is the only dependency except for the Android support library.

The errorenous inclusion seems to stem from a transitive dependency within JMRTD. Excluding or including this library (scuba) seems to make no difference.

I've also tried to add the library manually in my libs folder but am having the same issue.

Interestingly, if I exclude the transitive dependency completely like so...

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

... the preDexDebug step fails on a different file (which is natively part of the library and not included from a dependency):

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)

Side note: the files failing are the first files listed if you view the jar contents in alphabetical order, indicating that all class files would fail in the same way.

Is there some sort of internal duplication going on that I'm not aware of? The artifact I'm including seems fine on inspection but could there be an issue with the format of the files fetched from the repo?

Thanks!

Disclaimer: I'm new to Android and Gradle. I've got extensive experience with Maven and Java though.

Upvotes: 2

Views: 873

Answers (1)

halvdanhg
halvdanhg

Reputation: 198

For those who might be having similar issues: This turned out to be caused by a bad ant build for both of the libraries in question (jmrtd + scuba) which included each class file twice. This was hard to detect as some file managers will not list duplicate content of archives.

I eventually confirmed it by running 'tar tf ' to discover the diplicates and fixed it by building the libs myself with the ant jar-task attribute 'duplicate="preserve"'.

In general though, the root cause is the terrible default behaviour of ant to add two of the same file instead of failing/overwriting combined with the pickiness of Gradle when dealing with duplicates.

Upvotes: 3

Related Questions