2

The app contains a splash screen that displays briefly, and that activity is being tested with an instrumented test, using an IdlingResource so the test knows when the splash screen closes. The problem is that SplashActivity throws what looks like a dependency-related exception during test on devices running API 19:

import android.support.test.espresso.idling.CountingIdlingResource;
...
private CountingIdlingResource espressoTestIdlingResource =
new CountingIdlingResource("Splash_Delay"); // <-- Exception here line 22
...

app/build.gradle:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs'
        exclude module: 'espresso-idling-resource'
        exclude group: "javax.inject"
    })
    compile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'

    compile 'com.google.dagger:dagger:2.10'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.10'
    compile 'com.google.dagger:dagger-android:2.10'
    compile 'com.google.dagger:dagger-android-support:2.10'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.10'

    compile "com.android.support:appcompat-v7:$supportLibraryVersion"
    compile "com.android.support:design:$supportLibraryVersion"
    compile "com.android.support.constraint:constraint-layout:1.0.2"

    compile "com.jakewharton.timber:timber:4.5.1"
    compile "com.squareup.phrase:phrase:1.1.0"
    compile "com.squareup.retrofit2:retrofit:2.2.0"
    compile "com.squareup.retrofit2:converter-gson:2.2.0"
    compile "com.squareup.okhttp3:logging-interceptor:3.7.0"
    compile 'net.danlew:android.joda:2.9.9'

    testCompile 'junit:junit:4.12'
    compile 'com.google.firebase:firebase-crash:10.2.4'
    androidTestCompile 'junit:junit:4.12'
}

Exception:

java.lang.IllegalAccessError
java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
    at com.myapp.android.ui.splash.SplashActivity.<init>(SplashActivity.java:22)
    at java.lang.Class.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1208)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2101)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
    at android.app.ActivityThread.accessX800(ActivityThread.java:135)
    at android.app.ActivityThreadXH.handleMessage(ActivityThread.java:1196)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInitXMethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)

The exception occurs on an API level 19 Nexus 4 physical device in Firebase Test Lab. It does not occur on any other platforms we are testing on, including a local API 19 emulated Nexus S.

I understood the exception to mean there are ambiguous/duplicate (transitive) dependencies, but I cannot see any in gradlew dependencies, only Espresso Idling Resources v2.2.2. The dependency is "compile" not "androidTestCompile" as CountingIdlingResource is referenced in the Activity.

How do I identify the cause and resolve it?

UPDATE: The exception also occurs with API 19 on a Nexus 5 and Nexus 7. Here are the parts of the output of "./gradlew dependencies" relating to the idling resource library:

_debugApk - ## Internal use, do not manually configure ##
+--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
+--- com.google.dagger:dagger:2.10
...
_debugCompile - ## Internal use, do not manually configure ##
+--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
+--- com.google.dagger:dagger:2.10
...
_releaseApk - ## Internal use, do not manually configure ##
+--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
+--- com.google.dagger:dagger:2.10
...
_releaseCompile - ## Internal use, do not manually configure ##
+--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
+--- com.google.dagger:dagger:2.10
...
compile - Classpath for compiling the main sources.
+--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
+--- com.google.dagger:dagger:2.10
Ollie C
  • 28,313
  • 34
  • 134
  • 217
  • This is may be stupid suggestion, but did you disable animations before running tests on physical device ? – Anton Malmygin May 17 '17 at 08:37
  • The tests are running on BuddyBuild CI who use Firebase Test Lab for device testing, so I expect the animations are turned off and this seems very likely as I know many of the tests used to fail on a prior CI server until we turned them off. But I'm not sure animations is the issue as the app seems to be finding an unexpected class related to the idling resource, rather than failing in a more usual sense where the test verify fails. – Ollie C May 17 '17 at 10:39
  • Ok, I understand. I guess last time I saw this kind of similar problem was because espresso library was compiled with old version of Android support lib while I used the last one in my project. Again, I observed this only on Android 4.4 devices. So, finally only this workaround works for me - http://stackoverflow.com/a/28862902/2241008. Hope it helps you too. – Anton Malmygin May 17 '17 at 12:45
  • That issue is one where the dependency is referred to twice, but in my case it is only referred to once by my explicit reference to it. None of the other dependencies have transitive dependencies on the CountingIdlingResource. This class is defined in the Support Library, so is not included in API 19 on the device. The error makes no sense to me. – Ollie C May 19 '17 at 14:21
  • Which version of support library you are using ? Did you tried with old versions ? – Anton Malmygin May 19 '17 at 14:27
  • 25.3.1. I tried a couple of prior versions of the support library but it made no difference. Frustratingly the problem has since vanished, and I have no way to know what changed to cause it to start working. Initially I thought it was switching to the Google Maven repository, but I reverted and it still works fine on API 19. – Ollie C May 22 '17 at 13:41
  • Well, maybe it is still uses old support library :) You can try 'Clean project' / Disable instant run if you want to figure out for sure. Anyway, it is good that you do not have this problem anymore. – Anton Malmygin May 22 '17 at 14:22
  • I had tried clean rebuilds on my local machine without success, and the CI server always does a clean build and it didn't help unfortunately. – Ollie C May 23 '17 at 10:22

1 Answers1

6

As I understand Google Samples the dependency:

com.android.support.test.espresso:espresso-idling-resource:2.2.2

is only needed when you are implementing custom IdlingResource. Even in IdlingResourceSample README there is a sentence:

Consider using the CountingIdlingResource class from the espresso-contrib package

And as I understand your code you are trying to use CountingIdlingResource from espresso-contrib package, so try to organise your test dependencies as written in other Google sample.

R. Zagórski
  • 20,020
  • 5
  • 65
  • 90
  • I've marked this as the solution as you are very much correct that the dependency was incorrect and others may find it useful to check this. Unfortunately this did not fix the issue, and as it resolved itself I cannot say what the actual solution was. – Ollie C May 22 '17 at 13:43