How can gradle resolve conflicts when two dependencies have an internal dependency on the same library, but with different versions in Android?

My application has dependencies on two libraries. Both of them use the same org.hamcrest library : hamcrest-core , but different versions inside.

androidTestCompile 'junit:junit:4.12' //(Depends on version 1.3) androidTestCompile 'org.mockito:mockito-core:1.10.19' //(Depends on version 1.1) 

Since both dependencies are related to Android instrumentation tests , the application successfully completes and includes a higher version in the assembly - in this case version 1.3.

But if I use one library for the main application and another library for tests on the Android device as follows:

 compile 'junit:junit:4.12' androidTCompile 'org.mockito:mockito-core:1.10.19' 

I get the following error.

 :app:prepareDebugAndroidTestDependencies Conflict with dependency 'org.hamcrest:hamcrest-core'. Resolved versions for app (1.3) and test app (1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details. FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:prepareDebugAndroidTestDependencies'. > Dependency Error. See console for details. 

So, I went to the link indicated in the exception. The reason for this behavior is defined as follows:

When testing instrumentation, both the main APK and APK tests use the same class path. The Gradle construct will fail if the main APK and the test APK use the same library (e.g. Guava), but in different versions. If Gradle does not understand this, your application may behave differently during tests and during normal startup (including a crash in one of the cases).

I have no problems with this problem, but I have a problem in the following cases:

1) In the description below, only one main apk is created, because local tests are run in the JVM, why this happens with the same exception as the conflict.

 compile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' 

2) And if the foregoing fails, it must also fail. But it’s amazing that it works great and builds great.

  androidTestCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' 

I cannot understand this ambiguous nature with which gradle solves dependencies in Android .

+6
source share
1 answer

Explanation

As I understand it, testCompile dependencies also apply to androidTestCompile . Otherwise, you will need to enable junit twice, one for testCompile and one for androidTestCompile . Given this, your cases are easily explained:

1) testCompile includes androidTestCompile , so this case is obviously the same as the very first example in your question, so it makes sense for it to fail.

2) The compile not mentioned anywhere, so the main APK will not have any version of Hamcrest, so there can be no conflict between the main and test APKs.

Decision

the same page you provided also says:

To make the build successful, just make sure that both APKs use the same version. If the error is due to an indirect dependency (a library that you did not specify in your build.gradle), simply add the dependency for the newer version to the configuration ("compilation" or "androidTestCompile") that needs it. (...)

So, to prevent a conflict between the main and test APKs, you can explicitly indicate which version you want depending on the test, for example:

 compile 'junit:junit:4.12' androidTestCompile 'org.mockito:mockito-core:1.10.19' androidTestCompile 'org.hamcrest:hamcrest-core:1.3' 

Note:

Of course, very rarely do we have a good reason to include junit in the main APK. This fact does not invalidate the question, since many other dependencies may be between the main and test APKs other than junit, the most likely are support libraries.

0
source

Source: https://habr.com/ru/post/1013580/


All Articles