I'm trying to compile a module whose dependency tree looks like
+--- com.squareup.burst:burst-junit4:1.0.2
| +--- com.squareup.burst:burst:1.0.2
| \--- junit:junit:4.11 -> 4.12
| \--- org.hamcrest:hamcrest-core:1.3
+--- com.android.support.test.espresso:espresso-core:2.0
| +--- com.squareup:javawriter:2.1.1
| +--- org.hamcrest:hamcrest-integration:1.1
| | \--- org.hamcrest:hamcrest-core:1.1 -> 1.3
| +--- org.hamcrest:hamcrest-library:1.1
| | \--- org.hamcrest:hamcrest-core:1.1 -> 1.3
| +--- com.android.support.test.espresso:espresso-idling-resource:2.0
| +--- com.android.support.test:testing-support-lib:0.1
| | \--- junit:junit-dep:4.10
| | \--- org.hamcrest:hamcrest-core:1.1 -> 1.3
| +--- com.google.code.findbugs:jsr305:2.0.1
| +--- javax.annotation:javax.annotation-api:1.2
| \--- org.hamcrest:hamcrest-core:1.1 -> 1.3
...
As you can see there's a hamcrest-core
version conflict, but gradle appears to recognize the conflict and apply its default "latest version" strategy, which is exactly what I want.
However, when trying to run assembleDebugTest
(either manually or through Android Studio) I get
com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/MatcherAssert;
Some answers to similar questions suggest exclude
ing the unwanted jars, but I've encountered a bunch of similar conflicts, and it's getting a bit out of hand.
Why isn't gradle's default conflict strategy removing the older jar automatically? Does the android gradle plugin suppress that functionality?
Disabling transitive resolution You can tell Gradle to disable transitive dependency management for a dependency by setting ModuleDependency. setTransitive(boolean) to false . As a result only the main artifact will be resolved for the declared dependency.
Gradle contains a highly sophisticated dependency caching mechanism, which seeks to minimise the number of remote requests made in dependency resolution, while striving to guarantee that the results of dependency resolution are correct and reproducible.
Android Studio uses Gradle, an advanced build toolkit, to automate and manage the build process, while allowing you to define flexible custom build configurations. Each build configuration can define its own set of code and resources, while reusing the parts common to all versions of your app.
After some more digging, it seems the issue is that my dependency tree contained hamcrest-core
1.3 and hamcrest-integration
1.1, and MatcherAssert
was moved from hamcrest-integration
to hamcrest-core
between those versions.
So gradle was performing conflict resolution as documented; there was just a conflict between distinct modules which I didn't expect.
Forcing 1.3 for all three hamcrest modules took care of the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With