Question

I am trying to introduce Robolectric to an already existing android project. The project already runs a slew of espresso tests. As soon as I try to introduce robolectric, the tests fail with

java.lang.NoClassDefFoundError

Anyone have any thoughts? I'm using the gradle file below and used the Decard project as an example on brining in Robolectric.

apply plugin: 'android'
apply plugin: 'robolectric'
apply from : "$rootDir/gradle/signing.gradle"
apply from : "$rootDir/gradle/build_extras.gradle"
apply from : "$rootDir/gradle/environments.gradle"

loadConfiguration()

apply from : "$rootDir/gradle/checkstyle.gradle"
apply from : "$rootDir/gradle/pmd.gradle"
apply from : "$rootDir/gradle/findbugs.gradle"
apply from : "$rootDir/gradle/espresso.gradle"

android {
    compileSdkVersion 19
    buildToolsVersion '19.1'

    useOldManifestMerger true

    defaultConfig {
        applicationId ‘com.example.app'
        minSdkVersion 14
        targetSdkVersion 19
        versionCode getVersionCode()
        testInstrumentationRunner 'com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner'
    }

    packagingOptions {
        exclude 'LICENSE.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
    }

    lintOptions {
        abortOnError true
    }

    jacoco {
        version = '0.6.2.201302030002'
    }

    sourceSets {

        androidTest {
            setRoot('src/test')
        }

        debug.setRoot('build-types/debug')

    }

    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            debuggable true
            testCoverageEnabled false
        }
    }

    applicationVariants.all { variant ->
        removeSetAnimationScaleFromManifest(variant)

        task("generate${variant.name}Javadoc", type: Javadoc) {
            description "Generates Javadoc for $variant.name."
            group "Code Quality"

            def Properties localProperties = loadPropertiesFile('../local.properties')

            source = variant.javaCompile.source
            classpath = files(variant.javaCompile.classpath.files) +
                    files(localProperties['sdk.dir'] + "/platforms/android-4.4.2/android.jar")
        }

        copyAndRenameZipAlignedPackage(variant)
    }
}

apply plugin: 'monkey'

monkey {
    teamCityLog = false
    eventCount = 5000
    seed = 42
    failOnFailure = false
    install = false
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile project(':SlidingMenuLibrary')

    compile 'com.android.support:support-v4:19.1.+'
    compile 'com.google.android.gms:play-services:5.0.77'
    compile 'org.apache.james:apache-mime4j:0.6'
    compile 'org.apache.httpcomponents:httpmime:4.2.3'
    compile 'org.jsoup:jsoup:1.6.3'
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'com.googlecode.ez-vcard:ez-vcard:0.9.3'
    compile 'com.googlecode.libphonenumber:libphonenumber:5.9'

    // Espresso
    provided 'com.jakewharton.espresso:espresso:1.1-r3'
    androidTestCompile ('com.jakewharton.espresso:espresso:1.1-r3') {

    }
    androidTestCompile 'com.google.guava:guava:14.0.1'
    androidTestCompile 'com.squareup.dagger:dagger:1.1.0'
    androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'
    //androidTestCompile 'org.hamcrest:hamcrest-core:1.1'
    androidTestCompile 'org.hamcrest:hamcrest-library:1.1'

    androidTestCompile('junit:junit:4.11') {
        exclude module: 'hamcrest-core'
    }
    androidTestCompile('org.robolectric:robolectric:2.3') {
        exclude module: 'classworlds'
        exclude module: 'commons-logging'
        exclude module: 'httpclient'
        exclude module: 'maven-artifact'
        exclude module: 'maven-artifact-manager'
        exclude module: 'maven-error-diagnostics'
        exclude module: 'maven-model'
        exclude module: 'maven-project'
        exclude module: 'maven-settings'
        exclude module: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-provider-api'
    }
    androidTestCompile 'com.squareup:fest-android:1.0.+'
}

apply plugin: 'idea'

idea {
    module {
        testOutputDir = file('build/test-classes/debug')
    }
}

ErrorLog:

java.lang.NoClassDefFoundError: com/example/android/ui/GettingStarted

...

Caused by: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:222)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:215)
at dalvik.system.DexPathList.findClass(DexPathList.java:322)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
Was it helpful?

Solution

This happens when you have a class compiled into your test APK AND you app APK.

Run ./gradlew :app:dependencies and look for duplicates.

You may need to use "provided" instead of "compile" somewhere.

This has been discussed in lots of places:

http://www.sinking.in/blog/android-dependency-double-trouble/

java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation getting while running test project?

https://www.google.com/#q=java.lang.IllegalAccessError%3A+Class+ref+in+pre-verified+class+resolved+to+unexpected+implementation

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top