• 3
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

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 issue when running Android Tests either in AndroidStudio or via './gradlew connectedCheck'. What's the preferred way to resolve this?

'Warning:Conflict with dependency 'org.somelibrary:library-core'. Resolved versions for app and test app differ.'

As of Android Gradle Plugin 1.1.1 the error displays like this: "Warning:Conflict with dependency 'com.google.code.findbugs:jsr305'. Resolved versions for app (1.3.9) and test app (2.0.1) differ."

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.

  • 63
Reply Report
    • You say "we're hoping to fix this in a later release". Does that mean better reporting of the conflict, or supporting resolution of transitive dependencies across the app and test app?
      • 1
    • The next answer provides a great solution to determining the dependency version numbers until we improve this a bit. Although we don't suggest going to older versions of the plugin to stop the error from happening.
    • I've updated this answer to include the adjusted error message which automatically includes the version numbers.
    • Link to Gradle doc: gradle.org/docs/current/dsl/… (search for "forcing"). My error message is "Warning:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (22.0.0) and test app (20.0.0) differ." (same with and without "force"). Minimal dependencies that result in coflict are: compile 'com.android.support:support-annotations:22.0.0' and androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'

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'
  • 20
Reply Report
      • 1
    • Hi, How do you realize that app referring to annotations:21.0.3 and test app referring to 20.0.0? what is androidTestCompile 'com.squareup.assertj:assertj-android-appcompat-v7:1.0.0'. Please help.. It will be great help if I resolve this error.
      • 2
    • you'd noramlly see a warning in the messages view of android studio upon build. the message will state exactly this kind of mismatch+version names per app/test app.
      • 1
    • Thank you very much. If you mind me asking, why would it not work for me when I moved both of them down to an earlier version?
    • assertj is a library used for testing - that was just the issue in my case. it varies though. the point is that the plugin to 1.1.1 generates a more informative messages in your studio and tells you which component depends on which version of library in conflict. so one of them needs to use a newer one... newer cause backward compatibility is likelier than forward compatibility.

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' }

  • 6
Reply Report
      • 2
    • Despite not many votes this might be the simplest solution. You're only making changes to the library you're pulling in, not setting any 'force' resolution strategies, and not double-declaring the conflict library.

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.

  • 2
Reply Report