Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger code giving NoClassDefFoundError when Espresso Tests are run, normal run works fine

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)
like image 833
pturner Avatar asked Dec 24 '14 20:12

pturner


1 Answers

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;'
like image 170
Wes Avatar answered Sep 17 '22 19:09

Wes