1

i'm struggling since few days with a NoClassDefFoundError and the AndroidJUnitRunner in our MultiDex-Application...

Because we want to start using Espresso for our Click-Tests we changed our TestRunner from 'MultiDexTestRunner' to 'AndroidJUnitRunner'. With this change we got some problems with devices UNDER API 19. We get the response that 'no tests executed' cause of a NoClassDefFoundError when we execute our @SmallTests

In our Logcat we get the following information:

06-17 14:19:13.832 26531-26779/com.xxxxxx.debug E/AndroidRuntime: FATAL EXCEPTION: Instr: com.xxxxxxxx.test.WakefulTestRunner
java.lang.ExceptionInInitializerError
at android.support.test.internal.runner.TestRequestBuilder.addFromRunnerArgs(TestRequestBuilder.java:713)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:350)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
at com.xxxxxxxxxx.test.WakefulTestRunner.onStart(WakefulTestRunner.java:54)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1619)
Caused by: java.lang.NoClassDefFoundError: java.util.Objects
at android.support.test.internal.runner.TestSize.hashCode(TestSize.java:212)
at java.util.HashMap.put(HashMap.java:390)
at java.util.HashSet.add(HashSet.java:95)
at java.util.HashSet.<init>(HashSet.java:77)
at android.support.test.internal.runner.TestSize.<clinit>(TestSize.java:65)
at android.support.test.internal.runner.TestRequestBuilder.addFromRunnerArgs(TestRequestBuilder.java:713) 
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:350) 
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260) 
at com.xxxxxxxx.test.WakefulTestRunner.onStart(WakefulTestRunner.java:54) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1619) 

Here is the needed part of our WakefulTestRunner:

public class WakefulTestRunner extends AndroidJUnitRunner {

private PowerManager.WakeLock        wakeLock;
private KeyguardManager.KeyguardLock keyguardLock;

@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle arguments) {
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);

    String simpleName = WakefulTestRunner.class.getSimpleName();

    // Unlock the device so that the tests can input keystrokes.
    keyguardLock = ((KeyguardManager) getContext().getSystemService(KEYGUARD_SERVICE)).newKeyguardLock(simpleName);

    // Wake up the screen.
    int levelAndFlags = android.os.PowerManager.FULL_WAKE_LOCK
                        | android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP
                        | android.os.PowerManager.ON_AFTER_RELEASE;
    wakeLock = ((PowerManager) getContext().getSystemService(POWER_SERVICE)).newWakeLock(levelAndFlags, simpleName);
}

@Override
public void onStart() {
    runOnMainSync(new Runnable() {
        @Override
        public void run() {
            keyguardLock.disableKeyguard();
            wakeLock.acquire();
        }
    });

    super.onStart();
}

We also exclude a lot of different things in our build.gradle, but nothing helps:

configurations {
// This dependency set is for annotation processors.
// They're added below directly to the java compiler.
apt
androidTestCompile.exclude group: 'com.android.support', module: 'support-v4'
androidTestCompile.exclude group: 'com.android.support', module: 'recyclerview-v7'

androidTestCompile.exclude group: 'com.android.support', module: 'support-v13'
androidTestCompile.exclude group: 'com.android.support', module: 'appcompat-v7'
androidTestCompile.exclude group: 'com.android.support', module: 'cardview-v7'
}

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 23
    versionCode versionMajor * 10000 + versionMinor * 100 + versionMicro
    versionName "${versionMajor}.${versionMinor}.${versionMicro}"
    multiDexEnabled true

    //intended to fix install issue -505 (https://code.google.com/p/android/issues/detail?id=189079)
    applicationId = "com.xxxxxxxx"

    testInstrumentationRunner "com.xxxxxxxxx.test.WakefulTestRunner"
}
iFoukis
  • 274
  • 1
  • 2
  • 11
  • 1
    Objects was introduced in api level 19 - could be the issue... – assylias Jun 17 '16 at 12:52
  • 1
    It sounds like a good reason, but do u have an idea how to fix it or create a workaround for this? We have this problem since we changed to 'AndroidJUnitRunner'. – iFoukis Jun 17 '16 at 12:55
  • http://stackoverflow.com/questions/37778644/java-lang-noclassdeffounderror-java-util-objects – assylias Jun 17 '16 at 12:57
  • Thx, but as u can see in the logcat, the problems isn't occured in our code but in the code of 'android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260) ' – iFoukis Jun 17 '16 at 12:59
  • You can't use APIs introduced in API 19 and then use them in a lower API level. – Jared Burrows Oct 05 '16 at 15:46

1 Answers1

0

It's a bug in the AndroidJUnitRunner. https://code.google.com/p/android/issues/detail?id=213677

The workaround is to not use the test size flag with pre API 19 devices.

Crashes on api<19

./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.size=small

Works on all devices

./gradlew connectedAndroidTest
theJosh
  • 2,894
  • 1
  • 28
  • 50