简体   繁体   中英

NoClassDefFoundError for Android Espresso internal dagger factory class

I'm trying to add Espresso testing framework to my project. However, I'm stuck with this NoClassDefFoundError for 3 days. After searching over Google I found testing APK is using by default the DEBUG build type. For some reason I need to set Proguard on for debug build type. However, I get the following error when running my test configuration:

06-02 15:27:01.105 19436-19457/com.lingyue.YqgAndroid E/TestLoader: Could not find class: android.support.test.espresso.base.UiControllerModule_ProvideUiControllerFactory
06-02 15:27:01.107 19436-19457/com.lingyue.YqgAndroid I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.test.espresso.core.deps.dagger.internal.Factory>
06-02 15:27:01.107 19436-19457/com.lingyue.YqgAndroid I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.test.espresso.base.ViewFinderImpl_Factory>
06-02 15:27:01.107 19436-19457/com.lingyue.YqgAndroid I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.test.espresso.base.ViewFinderImpl_Factory>
06-02 15:27:01.109 19436-19457/com.lingyue.YqgAndroid E/TestLoader: Could not find class: android.support.test.espresso.base.ViewFinderImpl_Factory
06-02 15:27:01.114 19436-19457/com.lingyue.YqgAndroid I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.test.espresso.core.deps.dagger.internal.Factory>
06-02 15:27:01.115 19436-19457/com.lingyue.YqgAndroid E/AndroidRuntime: FATAL EXCEPTION: Instr: android.support.test.runner.AndroidJUnitRunner
    Process: com.lingyue.YqgAndroid, PID: 19436
    java.lang.NoClassDefFoundError: android.support.test.espresso.core.deps.dagger.internal.Factory
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:324)
    at android.support.test.internal.runner.TestLoader.doLoadClass(TestLoader.java:92)
    at android.support.test.internal.runner.TestLoader.loadIfTest(TestLoader.java:113)
    at android.support.test.internal.runner.TestRequestBuilder.loadClassesFromClassPath(TestRequestBuilder.java:801)
    at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:747)
    at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:354)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)

My build.gradle looks likes this for dependencies:

dependencies {
    compile "com.android.support:cardview-v7:${supportVersion}"
    compile "com.android.support:recyclerview-v7:${supportVersion}"
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
    compile 'com.loopj.android:android-async-http:1.4.9'
    compile 'com.qiniu:qiniu-android-sdk:7.0.9'
    compile 'com.mcxiaoke.gradle:packer-helper:1.0.4'
    compile 'me.henrytao:smooth-app-bar-layout:23.2.1.1'
    compile 'com.alipay.euler:andfix:0.4.0@aar'
    compile 'com.umeng.analytics:analytics:6.0.0'
    compile fileTree('libs')
    compile project(':framework')
    compile project(':yqdsdk')

    // Only needed at compilation
    provided 'com.google.dagger:dagger-compiler:2.0'
    provided 'org.glassfish:javax.annotation:10.0-b28'

    // For testing
    androidTestCompile "com.android.support:support-annotations:${supportVersion}"
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support.test:rules:0.5'
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
        exclude group: 'javax.inject'
    }
}

Build Types look like the following:

buildTypes {
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        testProguardFile 'test-proguard-rules.pro'
    }

    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

testProguardFile.pro looks like this:

-dontobfuscate
-dontwarn

What I've done:

  1. If I switch Proguard off for debug build by setting minifyEnabled=false, the test runs successfully . I get the error above otherwise.
  2. I tried to put testProguardFile under "defaultConfig" and "debug", but to no avail both.
  3. I tried to add one more build type "uiTest" with Proguard off, but the test configuration won't work after I set testBuildType to "uiTest". The error is that Android Studio won't recognise the test runner AndroidJUnitRunner.

It seems to me the problem comes with the mix use of proguard and dagger2 but I'm running out of ideas. Please help.

Best wishes

After doing more research, I found a solution for this problem although which is not straight forward:

  1. Add a new build type and sync the build the project, eg

    uiTest { minifyEnabled true }

  2. On the left down side of the Android Studio, click on "Build Variants". For your application module, choose the newly added build variant, eg "UiTest".

  3. Run the application.

This is somewhat inconvenient because you need to switch back and forth when you need to test under different build variants. But it gets Expresso running.

I had a similar problem and was able to fix it by adding the following rule to the proguard-rules.pro:

-keep class javax.inject.** { *; }

I'm not entirely sure your issue is the same though.
Also I'm not sure that you need to exclude javax.inject group from espresso-core dependency.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM