3

I am finally migrating my old unit tests that were run with JAR files to using gradle but I am having a lot of trouble getting the right combination and not sure what I am doing right or wrong. First of all, these are all the jar files that I am using.

dexmaker-1.0.jar
dexmaker-mockito-1.0.jar
fest-android-1.0.7.jar
fest-assert-core-2.0M10.jar
fest-util-1.2.5.jar
junit-4.11.jar
mockito-all-1.9.5.jar
the-missing-android-xml-junit-test-runner-release-1.3_2.jar  <---- I think this is used to get reports for the unit tests, is there a way that I don't have to use this anymore?

When I have all these JARs imported just as JARs like the following it works fine, so that is a good thing, but not ideal:

androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')

Next, I went about trying to change all the JAR files to gradle-maven dependencies such as the following

androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')
androidTestCompile 'junit:junit:4.11+'
androidTestCompile ('com.squareup:fest-android:1.0.+') {
    exclude group: 'com.android.support'
}
androidTestCompile 'org.easytesting:fest-assert-core:2.0M10'
androidTestCompile 'org.easytesting:fest-util:1.2.+'
androidTestCompile 'org.mockito:mockito-all:1.9.+'
androidTestCompile 'com.google.dexmaker:dexmaker:1.+'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.+'

This didn't work because when trying to build and run the unit tests, I got the following result:

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/Description;
    at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:594)
    at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:552)
    ... 

So I looked at a few places to help me solve this at, Android Gradle DexException: Multiple dex files define Lorg/hamcrest/Description Android testing: 'Multiple dex files' when using 'gradle check connectedCheck' Android + Powermock + Mockito + Maven build error with ClassNotFoundException, and they suggested that I try the following:

androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')
androidTestCompile('junit:junit:4.11+') {
    exclude group: 'org.hamcrest'
}
androidTestCompile ('com.squareup:fest-android:1.0.+') {
    exclude group: 'com.android.support'
}
androidTestCompile 'org.easytesting:fest-assert-core:2.0M10'
androidTestCompile 'org.easytesting:fest-util:1.2.+'
androidTestCompile 'org.mockito:mockito-all:1.9.+'
androidTestCompile 'com.google.dexmaker:dexmaker:1.+'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.+'

and

androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')
androidTestCompile 'junit:junit:4.11+'
androidTestCompile ('com.squareup:fest-android:1.0.+') {
    exclude group: 'com.android.support'
}
androidTestCompile 'org.easytesting:fest-assert-core:2.0M10'
androidTestCompile 'org.easytesting:fest-util:1.2.+'
androidTestCompile('org.mockito:mockito-all:1.9.5') {
    exclude group: 'org.hamcrest'
}
androidTestCompile 'com.google.dexmaker:dexmaker:1.+'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.+'

but the still yielded the following:

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/Description;
    at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:594)
    at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:552)

I tried the following to change the junit and mockito according to some recommendations.

androidTestCompile 'junit:junit-dep:4.11+'
androidTestCompile 'org.mockito:mockito-core:1.9.+'

and I got

Error: duplicate files during packaging of APK /.../app/build/outputs/apk/app-debug-test-unaligned.apk
Path in archive: LICENSE.txt
Origin 1: /.../.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar
Origin 2: /.../.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar
You can ignore those files in your build.gradle:
android {
  packagingOptions {
    exclude 'LICENSE.txt'
  }
}
FAILED
FAILURE: Build failed with an exception.
Execution failed for task ':app:packageDebugTest'.

Duplicate files copied in APK LICENSE.txt File 1: /Users/simonadmin/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar File 2: /Users/simonadmin/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar

Any recommendations or help with this? I don't want to go back to using the JARs.

Community
  • 1
  • 1
lazypig
  • 747
  • 1
  • 6
  • 22
  • I'm had the exact error pop up a few hours ago. I left the jars in the lib folder at the same time trying to download them from maven repo using gradle. Did you make sure you removed the jars from the local lib before you tried to download them from the repo? – LEO Aug 01 '14 at 20:38
  • Related: [Android Gradle DexException: Multiple dex files define Lorg/hamcrest/Description](http://stackoverflow.com/questions/22702267/android-gradle-dexexception-multiple-dex-files-defined) – blahdiblah Dec 14 '16 at 00:35

2 Answers2

17

Actually, I figured it out at the end by just adding and it worked.

android {
    // stuff before

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

And my dependencies have the following

dependencies {
    androidTestCompile ('com.squareup:fest-android:1.0.+') {
        exclude group: 'com.android.support'
    }
    androidTestCompile 'com.google.dexmaker:dexmaker:1.+'
    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.+'

    androidTestCompile 'junit:junit:4.11'
    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
    androidTestCompile 'org.mockito:mockito-core:1.9.5'
}
lazypig
  • 747
  • 1
  • 6
  • 22
0

I am also facing the same issue.

Well @lazypig has mentioned the final version of his build.gradle sections.

But the reason is that org.hamcrest.Description is packaged in mockito-all.jar. Hence, when the dependency was changed to mockito-core, there was only one hamcrest-core.jar in the classpath which came from junit.jar.

However, I am still not able to figure out why the exclude is not working in this scenario!

TechSpellBound
  • 2,505
  • 6
  • 25
  • 36
  • 1
    My guess is that the problem is not in `exclude`, but in `mockito-all.jar` packaging. My guess is that Mockito authors have copied some classes from `hamcrest-library` instead of using dependency and Gradle build is seeing those classes as different. – Aleksandar Ilic Nov 17 '15 at 12:10
  • 1
    I checked the mockito-all package code. They indeed have copied some classes. I find this practise really weird. – sid_09 Mar 01 '17 at 08:58