androiddagger-hiltinstrumented-test

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/test/platform/io/FileTestStorage


I have an Android multi-module project, in which one I a trying to run instrumented tests. My "feature" modules are android libraries and the instrumented tests run correctly.

But I have an issue while I am trying to run the example instrumented test from the "app" module which is an Android Application.

Here the instrumented test I am trying to run:

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {

  @Test
  fun useAppContext() {
    // Context of the app under test.
    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
    assertEquals("my.package.name.test", appContext.packageName)
  }
}

When I try to run the command line ./gradlew :app:create[Flavor]DebugCoverageReport, it fails with the following stackstrace:

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/test/platform/io/FileTestStorage;
        at androidx.test.runner.AndroidJUnitRunner.registerTestStorage(AndroidJUnitRunner.java:677)
        at androidx.test.runner.AndroidJUnitRunner.onCreate(AndroidJUnitRunner.java:321)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6990)
        at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:205)
        at android.os.Looper.loop(Looper.java:294)
        at android.app.ActivityThread.main(ActivityThread.java:8177)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

After some investigation, it seems that the FileTestStorage class comes from the androidx.test:monitor artifact. I do not reference this dependency so it seems to be a transitive one. And if I check into the External Librairies of my Android Studio project, I can find this:

androidx test monitor in two versions

I have 2 versions of the androidx.test:monitor librairy in my project:

I first try to force the use of the version 1.7.2 by adding the lib a dependency through my convention plugin: add("androidTestImplementation", "androidx.test:monitor:1.7.2"). unfortunately, it fails with the following stacktrace:

> Could not resolve all files for configuration ':app:fubukiGoogleDebugAndroidTestRuntimeClasspath'.
   > Could not resolve androidx.test:monitor:1.7.2.
     Required by:
         project :app
         project :app > androidx.test:runner:1.6.2
      > Cannot find a version of 'androidx.test:monitor' that satisfies the version constraints:
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test:monitor:1.7.2'
           Constraint path 'Arrowwords:app:unspecified' --> 'androidx.test:monitor:{strictly 1.4.0}' because of the following reason: version resolved in configuration ':app:fubukiGoogleDebugRuntimeClasspath' by consistent resolution
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test.ext:junit:1.2.1' (runtime) --> 'androidx.test:monitor:1.7.1'
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test.espresso:espresso-core:3.6.1' (runtime) --> 'androidx.test:monitor:1.7.1'
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test:runner:1.6.2' (runtime) --> 'androidx.test:monitor:1.7.2'
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test.ext:junit:1.2.1' (runtime) --> 'androidx.test.services:storage:1.5.0' (runtime) --> 'androidx.test:monitor:1.7.0'
           Dependency path 'Arrowwords:app:unspecified' --> 'androidx.test.ext:junit:1.2.1' (runtime) --> 'androidx.test:core:1.4.0' (runtime) --> 'androidx.test:monitor:1.4.0'

So I checked the dependencies graph and I found these information:

+--- com.google.dagger:hilt-android-testing:2.55
|    +--- androidx.test:core:1.4.0
|    |    +--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*)
|    |    +--- androidx.test:monitor:1.4.0
|    |    |    \--- androidx.annotation:annotation:1.0.0 -> 1.8.1 (*)
|    |    \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.8.7 (*)
[...]
+--- androidx.test:core:{strictly 1.4.0} -> 1.4.0 (c)

If I guess that the issue come from the com.google.dagger:hilt-android-testing artifact. This artifact strictly need the version 1.4.0 of the androidx.test:core that comes with the version 1.4.0 of the androidx.test:monitor library.

if I remove the com.google.dagger:hilt-android-testing artifact from my dependencies and I gradle sync my project it seems that the artifact androidx.test:monitor:1.4.0 disappears:

just one version]2

Also note that even if the dependency graph says that I use com.google.dagger:hilt-android-testing:2.55 in reality, the version 2.56.

I need this dependency since I use Hilt in my project but it seems also to be a blocker for the instrumented test of my "app" module.

How can I fix this issue?


Solution

  • I fixed the issue by forcing the latest version of the core and monitor version using :

    configurations.all {
        resolutionStrategy {
          force(libs.test.android.core, libs.test.android.monitor)
        }
      }