Dependency conflict error in my Android app which has Android Tests

后端 未结 5 2054
[愿得一人]
[愿得一人] 2020-12-08 13:46

I\'m using AndroidStudio and Gradle to build my Android app with tests in the \'androidTest\' source directory. I added a new dependency and am now getting the following iss

相关标签:
5条回答
  • 2020-12-08 14:00

    When you build and run Android Tests for your app the Android Gradle plugin builds two APKs (the app and the test APK). During the gradle run the dependencies for the app and test builds are compared. Dependencies that exist in both are removed from the test build when the version numbers are the same. When the same dependencies are in use, but differ by version number then you will need to manually resolve the dependency conflict and this error is presented.

    To resolve the conflict you first need to figure out the two versions that are conflicting. If you aren't already using the Android Gradle Plugin v1.1.1+ then if you upgrade to that version the error message will give you the conflicting version numbers. Choose which one you need.

    *When choosing between the conflict numbers it might be important to keep in mind that unless you've overridden the default gradle dependency resolution strategy (failOnVersionConflict) then conflicts internally within the app and test builds (separately) will be resolved by choosing the greater version.

    Now you need to decide how to resolve the conflict. If you need to force the use of the lower version (1.2) of the library you will need to force the dependency to be resolved for both the app and test builds to a specific version of the library like this:

    // Needed to resolve app vs test dependencies, specifically, transitive dependencies of
    // libraryq and libraryz. Forcing the use of the smaller version after regression testing.
    configurations.all {
        resolutionStrategy.force 'org.somelibrary:library-core:1.2'
    }
    

    If you need to use the 2.1 version of the dependency then you can use the snippet above as well, but you will never start using a newer version of the library regardless of whether transitive dependency updates require it. Alternatively, you can also add a new normal dependency to either the app or the test builds (whichever was trying to use the 1.2 version of the dependency). This will force the app or test build to depend on the (previously mentioned) gradle dependency resolution strategy and therefore use the 2.1 version of the library for that build.

    // Force the use of 2.1 because the app requires that version in libraryq transitively.
    androidTestCompile 'org.somelibrary:library-core:2.1'
    

    or

    // Force the use of 2.1 because the Android Tests require that version in libraryz.
    compile 'org.somelibrary:library-core:2.1'
    

    In this solution the error could resurface, if say version 3.3, started to be used in only one of either the test or the app builds, but this is typically OK because you'll be notified of another incompatibility at build time and can take action.

    Update: A few new solutions to this question now also list excluding a particular transitive dependency from a declared dependency. This is a valid solution, but puts more onus on the developers. In the same way that the forced dependency resolution suggestion above above hard codes a version into the build, the exclude-transitive-dependency solution specifically overrides the stated requirements of a library. Sometimes library developers have bugs or work around bugs in various other libraries so when you implement these solutions you take some risk in potentially having to chase down very obscure bugs.

    0 讨论(0)
  • 2020-12-08 14:01

    Alternatively, one can exclude the conflicting dependency (e.g. support annotations library) pulled in by the test app dependency (e.g. assertj-android), by using the following:

    testCompile('com.squareup.assertj:assertj-android:1.0.0') { exclude group: 'com.android.support', module: 'support-annotations' }

    0 讨论(0)
  • 2020-12-08 14:05

    Had similar problem. First - I upgrade the gradle plugin to 1.1.1 (in the project's gradle):

    classpath 'com.android.tools.build:gradle:1.1.1'
    

    which helped me realize that the problem was the app referring to:

    com.android.support:support-annotations:21.0.3
    

    while the test app was referring to:

    com.android.support:support-annotations:20.0.0  
    

    (due to specifying androidTestCompile 'com.squareup.assertj:assertj-android-appcompat-v7:1.0.0')

    solved it by specifying:

    androidTestCompile 'com.android.support:support-annotations:21.0.3'
    
    0 讨论(0)
  • 2020-12-08 14:10

    Gradle has Resolution Strategy Mechanism.

    You can resolve this conflict by adding below lines to app level build.gradle file:

    configurations.all {
        resolutionStrategy {
            force 'com.google.code.findbugs:jsr305:1.3.9', 'com.google.code.findbugs:jsr305:2.0.1'
        }
    }
    
    0 讨论(0)
  • 2020-12-08 14:21

    If you look at the (generated) .iml file(s), you can see the conflicting version numbers quite easily. In my case:

    <orderEntry type="library" exported="" scope="TEST" name="support-annotations-20.0.0" level="project" />
    <orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
    

    Going back to version 1.0.1 of the gradle plugin resolves the problem.

    0 讨论(0)
提交回复
热议问题