Dagger code giving NoClassDefFoundError when Espre

2020-03-09 08:42发布

问题:

Started exploring Espresso 2.0, but seem to have run into a hiccup. I cannot get the tests to successfully run against any project which includes Dagger. When I run the tests I get the following Exception (entire stacktrace at the end):

java.lang.NoClassDefFoundError: com/pdt/daggerexample/model/DaggerExampleAppModule$$ModuleAdapter$ProvideMySingletonProvidesAdapter

The application runs when not running from the AndroidInstrumentationTest.

Here are some of the relevant files, I've also uploaded the project to github to allow for a quicker checkout/reproduction https://github.com/paul-turner/espressoDaggerExample.

build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.pdt.daggerexample"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        minSdkVersion 16
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
        }


    }

    packagingOptions {
        exclude 'LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.jakewharton:butterknife:5.1.1'
    compile 'com.squareup.dagger:dagger:1.2.2'
    provided 'com.squareup.dagger:dagger-compiler:1.2.2'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
}

Test:

public class SampleEspressoTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public SampleEspressoTest() {
        super(MainActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        // Espresso will not launch our activity for us, we must launch it via getActivity().
        getActivity();
    }

    public void testCheckText() {
        onView(ViewMatchers.withId(com.pdt.daggerexample.R.id.espresso_test))
                .check(matches(withText("Espresso Test")));
    }
}

Module:

package com.pdt.daggerexample.model;

import com.pdt.daggerexample.inject.DaggerExampleApplication;
import com.pdt.daggerexample.MainActivity;
import com.pdt.daggerexample.SecondActivity;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

@Module(injects = {
        MainActivity.class,
        SecondActivity.class,
}, complete = true)

public class DaggerExampleAppModule {

    private final DaggerExampleApplication mDaggerExampleApplication;

    public DaggerExampleAppModule(DaggerExampleApplication daggerExampleApplication) {
        mDaggerExampleApplication = daggerExampleApplication;
    }

    @Provides
    @Singleton
    public MySingleton provideMySingleton() {
        return new MySingleton(mDaggerExampleApplication.getApplicationContext(), "FOOBAR!");
    }

    @Provides
    public MyRegularOldClassInstance provideMyRegularOldClassInstance() {
        return new MyRegularOldClassInstance();
    }

}

Stacktrace:

    12-24 15:18:17.986    1282-1282/? E/MonitoringInstrumentation﹕ Dying now...
    12-24 15:18:17.986    1282-1282/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
        java.lang.NoClassDefFoundError: com/pdt/daggerexample/model/DaggerExampleAppModule$$ModuleAdapter$ProvideMySingletonProvidesAdapter
                at com.pdt.daggerexample.model.DaggerExampleAppModule$$ModuleAdapter.getBindings(DaggerExampleAppModule$$ModuleAdapter.java:28)
                at com.pdt.daggerexample.model.DaggerExampleAppModule$$ModuleAdapter.getBindings(DaggerExampleAppModule$$ModuleAdapter.java:13)
                at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:185)
                at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
                at dagger.ObjectGraph.create(ObjectGraph.java:129)
                at com.pdt.daggerexample.inject.DaggerExampleApplication.onCreate(DaggerExampleApplication.java:16)
                at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
                at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151)
                at android.app.ActivityThread.access$1300(ActivityThread.java:130)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
                at android.os.Handler.dispatchMessage(Handler.java:99)
                at android.os.Looper.loop(Looper.java:137)
                at android.app.ActivityThread.main(ActivityThread.java:4745)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:511)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                at dalvik.system.NativeStart.main(Native Method)
         Caused by: java.lang.ClassNotFoundException: com.pdt.daggerexample.model.DaggerExampleAppModule$$ModuleAdapter$ProvideMySingletonProvidesAdapter
                at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
                at com.pdt.daggerexample.model.DaggerExampleAppModule$$ModuleAdapter.getBindings(DaggerExampleAppModule$$ModuleAdapter.java:28)
                at com.pdt.daggerexample.model.DaggerExampleAppModule$$ModuleAdapter.getBindings(DaggerExampleAppModule$$ModuleAdapter.java:13)
                at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:185)
                at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
                at dagger.ObjectGraph.create(ObjectGraph.java:129)
                at com.pdt.daggerexample.inject.DaggerExampleApplication.onCreate(DaggerExampleApplication.java:16)
                at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
                at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151)
                at android.app.ActivityThread.access$1300(ActivityThread.java:130)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
                at android.os.Handler.dispatchMessage(Handler.java:99)
                at android.os.Looper.loop(Looper.java:137)
                at android.app.ActivityThread.main(ActivityThread.java:4745)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:511)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                at dalvik.system.NativeStart.main(Native Method)

回答1:

This issue had me for a bit. You likely need to exclude javax.inject from the espresso dependency. Earlier versions of Android appear to be less tolerant of identical dependencies.

Something along the lines of:

androidTestCompile ('com.android.support.test.espresso:espresso-core:2.0') {
    exclude group: 'javax.inject'
}

Beware that this can bite you all over the place. The emulator device logs have some useful hints about where the collisions are taking place. E.g.:

(Ldagger/internal/Binding; had used a different Ljavax/inject/Provider; during pre-verification) 

or

DexOpt: not resolving ambiguous class 'Ljunit/framework/TestSuite;'


回答2:

I've solved this problem adding to gradle the following code:

configurations {
    androidTestCompile.exclude group: 'com.android.support', module: 'support-v4'
}