2

I know that asking this type of question without specifics is very difficult, however; the project that is having the problem is proprietary and I have not been able to reproduce the issue in any other project.

So I've added the following to my build.gradle file:

androidTestCompile('com.jakewharton.espresso:espresso:1.1-r3') {
    exclude group: 'com.square.dagger'
}
androidTestCompile('com.jakewharton.espresso:espresso-support-v4:1.1-r3') {
    exclude group: 'com.android.support'
}

I do have two product flavors defined as well, neither are working. The test class I have is:

   public class MainActivityInstrumentationTest extends ActivityInstrumentationTestCase2<MainActivity> {
       private MainActivity myActivity;
       private Spinner spinner;

       public MainActivityInstrumentationTest() {
         super(MainActivity.class);
        }
        protected void setUp() throws Exception {
          super.setUp();

          myActivity = getActivity();
          spinner = (Spinner)myActivity.findViewById(R.id.watch_category);
        }

        public void testTextView() {
          assertOnScreen(myActivity.getWindow().getDecorView(), spinner);
        }
    }

Now in studio it finds MainActivity.class just fine and adds the correct import. However; when I run the test the constructor throws an exception that fully qualified path to the .class is not found. I've tried running gradle with --debug and I don't see anything out of the ordinary. The apk file that is generated has a classes.dex and using dex2jar I see the MainActivity.class in there. So at this point at a bit of a loss as to why the class file is not found during the test execution. Does anyone have any other methods that I can try to debug this situation, like I said I have other projects that work just fine and I'm not able to modify them to exhibit this behavior.

Any assistance in this would be greatly appreciated.

EDIT: Full trace from logcat

W/dalvikvm( 4371): Class resolved by unexpected DEX: Landroid/support/v7/app/ActionBarActivity;(0xa501f5e8):0x94c6a000 ref [Landroid/support/v4/app/FragmentActivity;] Landroid/support/v4/app/FragmentActivity;(0xa501f5e8):0x9528b000
W/dalvikvm( 4371): (Landroid/support/v7/app/ActionBarActivity; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification)
W/dalvikvm( 4371): Unable to resolve superclass of Landroid/support/v7/app/ActionBarActivity; (282)
W/dalvikvm( 4371): Link of class 'Landroid/support/v7/app/ActionBarActivity;' failed
W/dalvikvm( 4371): Unable to resolve superclass of Lcom/mycompany/mypackage/MainActivity; (763)
W/dalvikvm( 4371): Link of class 'Lcom/mycompany/mypackage/MainActivity;' failed
E/dalvikvm( 4371): Could not find class 'com.mycompany.myapp.MainActivity', referenced from method com.mycompany.myapp.tests.MainActivityInstrumentationTest.<init>
W/dalvikvm( 4371): VFY: unable to resolve const-class 2880 (Lcom/mycompany/mypackage/MainActivity;) in Lcom/mycompany/mypackage/tests/MainActivityInstrumentationTest;
D/dalvikvm( 4371): VFY: replacing opcode 0x1c at 0x0000
W/dalvikvm( 4371): Class resolved by unexpected DEX: Landroid/support/v7/app/ActionBarActivity;(0xa501f5e8):0x94c6a000 ref [Landroid/support/v4/app/FragmentActivity;] Landroid/support/v4/app/FragmentActivity;(0xa501f5e8):0x9528b000
W/dalvikvm( 4371): (Landroid/support/v7/app/ActionBarActivity; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification)
W/dalvikvm( 4371): Unable to resolve superclass of Landroid/support/v7/app/ActionBarActivity; (282)
W/dalvikvm( 4371): Link of class 'Landroid/support/v7/app/ActionBarActivity;' failed
W/dalvikvm( 4371): Unable to resolve superclass of Lcom/mycompany/mypackage/MainActivity; (763)
W/dalvikvm( 4371): Link of class 'Lcom/mycompany/mypackage/MainActivity;' failed
E/dalvikvm( 4371): Could not find class 'com.mycompany.myapp.MainActivity', referenced from method com.mycompany.myapp.tests.MainActivityInstrumentationTest.setUp
W/dalvikvm( 4371): VFY: unable to resolve check-cast 2880 (Lcom/mycompany/mypackage/MainActivity;) in Lcom/mycompany/mypackage/tests/MainActivityInstrumentationTest;
D/dalvikvm( 4371): VFY: replacing opcode 0x1f at 0x0007
D/dalvikvm( 4371): GC_FOR_ALLOC freed 261K, 10% free 3376K/3712K, paused 2ms, total 2ms
W/dalvikvm( 4371): Class resolved by unexpected DEX: Landroid/support/v7/app/ActionBarActivity;(0xa501f5e8):0x94c6a000 ref [Landroid/support/v4/app/FragmentActivity;] Landroid/support/v4/app/FragmentActivity;(0xa501f5e8):0x9528b000
W/dalvikvm( 4371): (Landroid/support/v7/app/ActionBarActivity; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification)
W/dalvikvm( 4371): Unable to resolve superclass of Landroid/support/v7/app/ActionBarActivity; (282)
W/dalvikvm( 4371): Link of class 'Landroid/support/v7/app/ActionBarActivity;' failed
W/dalvikvm( 4371): Unable to resolve superclass of Lcom/mycompany/mypackage/MainActivity; (763)
W/dalvikvm( 4371): Link of class 'Lcom/mycompany/mypackage/MainActivity;' failed
W/dalvikvm( 4371): Class resolved by unexpected DEX: Landroid/support/v7/app/ActionBarActivity;(0xa501f5e8):0x94c6a000 ref [Landroid/support/v4/app/FragmentActivity;] Landroid/support/v4/app/FragmentActivity;(0xa501f5e8):0x9528b000
W/dalvikvm( 4371): (Landroid/support/v7/app/ActionBarActivity; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification)
W/dalvikvm( 4371): Unable to resolve superclass of Landroid/support/v7/app/ActionBarActivity; (282)
W/dalvikvm( 4371): Link of class 'Landroid/support/v7/app/ActionBarActivity;' failed
W/dalvikvm( 4371): Unable to resolve superclass of Lcom/mycompany/mypackage/MainActivity; (763)
W/dalvikvm( 4371): Link of class 'Lcom/mycompany/mypackage/MainActivity;' failed
I/dalvikvm( 4371): Could not find method com.mycompany.myapp.MainActivity.getWindow, referenced from method com.mycompany.myapp.tests.MainActivityInstrumentationTest.testTextView
W/dalvikvm( 4371): VFY: unable to resolve virtual method 21012: Lcom/mycompany/mypackage/MainActivity;.getWindow ()Landroid/view/Window;
D/dalvikvm( 4371): VFY: replacing opcode 0x6e at 0x0002
D/dalvikvm( 4371): GC_FOR_ALLOC freed 348K, 11% free 3541K/3964K, paused 2ms, total 2ms
I/System.out( 4371): Sending WAIT chunk
I/dalvikvm( 4371): Debugger is active
I/System.out( 4371): Debugger has connected
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): waiting for debugger to settle...
I/System.out( 4371): debugger has settled (1483)
I/TestRunner( 4371): started: warning(junit.framework.TestSuite$1)
I/GoogleInstr( 4371): Activities that are still in CREATED to PAUSED: 0
I/TestRunner( 4371): failed: warning(junit.framework.TestSuite$1)
I/TestRunner( 4371): ----- begin exception -----
I/TestRunner( 4371):
I/TestRunner( 4371): junit.framework.AssertionFailedError: Exception in constructor: testTextView (java.lang.NoClassDefFoundError: com.mycompany.myapp.MainActivity
I/TestRunner( 4371):  at com.mycompany.myapp.tests.MainActivityInstrumentationTest.<init>(MainActivityInstrumentationTest.java:19)
I/TestRunner( 4371):  at java.lang.reflect.Constructor.constructNative(Native Method)
I/TestRunner( 4371):  at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
I/TestRunner( 4371):  at junit.framework.TestSuite.createTest(TestSuite.java:61)
I/TestRunner( 4371):  at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)
I/TestRunner( 4371):  at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)
I/TestRunner( 4371):  at junit.framework.TestSuite.<init>(TestSuite.java:129)
I/TestRunner( 4371):  at junit.runner.BaseTestRunner.getTest(BaseTestRunner.java:118)
I/TestRunner( 4371):  at android.test.AndroidTestRunner.getTest(AndroidTestRunner.java:149)
I/TestRunner( 4371):  at android.test.AndroidTestRunner.setTestClassName(AndroidTestRunner.java:57)
I/TestRunner( 4371):  at android.test.suitebuilder.TestSuiteBuilder.addTestClassByName(TestSuiteBuilder.java:80)
I/TestRunner( 4371):  at android.test.InstrumentationTestRunner.parseTestClass(InstrumentationTestRunner.java:443)
I/TestRunner( 4371):  at android.test.InstrumentationTestRunner.parseTestClasses(InstrumentationTestRunner.java:424)
I/TestRunner( 4371):  at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:370)
I/TestRunner( 4371):  at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onCreate(GoogleInstrumentationTestRunner.java:114)
I/TestRunner( 4371):  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4335)
I/TestRunner( 4371):  at android.app.ActivityThread.access$1500(ActivityThread.java:135)
I/TestRunner( 4371):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
I/TestRunner( 4371):  at android.os.Handler.dispatchMessage(Handler.java:102)
I/TestRunner( 4371):  at android.os.Looper.loop(Looper.java:136)
I/TestRunner( 4371):  at android.app.ActivityThread.main(ActivityThread.java:5017)
I/TestRunner( 4371):  at java.lang.reflect.Method.invokeNative(Native Method)
I/TestRunner( 4371):  at java.lang.reflect.Method.invoke(Method.java:515)
I/TestRunner( 4371):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
I/TestRunner( 4371):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
I/TestRunner( 4371):  at dalvik.system.NativeStart.main(Native Method)
I/TestRunner( 4371): )
I/TestRunner( 4371):  at junit.framework.Assert.fail(Assert.java:50)
I/TestRunner( 4371):  at junit.framework.TestSuite$1.runTest(TestSuite.java:97)
I/TestRunner( 4371):  at junit.framework.TestCase.runBare(TestCase.java:134)
I/TestRunner( 4371):  at junit.framework.TestResult$1.protect(TestResult.java:115)
I/TestRunner( 4371):  at junit.framework.TestResult.runProtected(TestResult.java:133)
I/TestRunner( 4371):  at junit.framework.TestResult.run(TestResult.java:118)
I/TestRunner( 4371):  at junit.framework.TestCase.run(TestCase.java:124)
I/TestRunner( 4371):  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
I/TestRunner( 4371):  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
I/TestRunner( 4371):  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
I/TestRunner( 4371):  at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167)
I/TestRunner( 4371):  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
I/TestRunner( 4371): ----- end exception -----
I/TestRunner( 4371): finished: warning(junit.framework.TestSuite$1)
I/GoogleInstr( 4371): Activities that are still in CREATED to PAUSED: 0
I/GoogleInstr( 4371): waitForActivitiesToComplete() took: 0ms
D/AndroidRuntime( 4361): Shutting down VM

Edit: build.gradle dependencies

dependencies {
    compile 'com.mcxiaoke.volley:library-aar:1.0.+'
    compile 'com.android.support:support-v4:19.0.+'
    compile 'com.android.support:appcompat-v7:19.0.+'
    compile 'com.google.android.gms:play-services:4.2.42'
    compile 'com.arcbees:facebook:1.1.1'
    compile 'com.facebook:facebook-android-sdk:3.5.2@aar'
    compile 'com.j256.ormlite:ormlite-android:4.47'
    compile 'com.j256.ormlite:ormlite-core:4.47'
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'org.slf4j:slf4j-api:1.7.5'
    compile 'com.github.tony19:logback-android-classic:1.1.1-3'
    compile 'com.crashlytics.android:crashlytics:1.+'
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'com.squareup.dagger:dagger:1.0.1'
    compile 'com.squareup.dagger:dagger-compiler:1.0.1'
    compile 'com.jakewharton:butterknife:1.3.2'
    compile 'com.actionbarsherlock:viewpagerindicator:2.4.1'
    compile 'com.squareup:otto:1.3.4'
    compile 'com.squareup.picasso:picasso:1.1.1'
    compile 'com.squareup.retrofit:retrofit:1.2.2'
    compile 'com.github.machinarius:preferencefragment:0.1.1'
    compile files('libs/cwac-wakefulintentservice.jar')
    compile files('libs/libGoogleAnalyticsServices.jar')
    compile files('libs/android-switch-backport.jar')
    compile files('libs/google-api-client-googleapis-1.4.1-beta.jar')

    androidTestCompile 'com.squareup:fest-android:1.0.+'
    androidTestCompile('com.jakewharton.espresso:espresso:1.1-r3') {
        exclude group: 'com.square.dagger'
    }
    androidTestCompile('com.jakewharton.espresso:espresso-support-v4:1.1-r3') {
        exclude group:'com.android.support', module:'support-v4'
        exclude group:'com.android.support', module:'appcompat-v7'
    }
}

Update: After making updating the dependecies I still get the NoClassDefFoundError and in logcat I see

W/dalvikvm( 3373): Class resolved by unexpected DEX: Lcom/mycompany/mypackage/MainActivity;(0xa50a6d18):0x94ba7000 ref [Landroid/support/v7/app/ActionBarActivity;] Landroid/support/v7/app/ActionBarActivity;(0xa50a6d18):0x95318000
W/dalvikvm( 3373): (Lcom/mycompany/mypackage/MainActivity; had used a different Landroid/support/v7/app/ActionBarActivity; during pre-verification)
W/dalvikvm( 3373): Unable to resolve superclass of Lcom/mycompany/mypackage/MainActivity; (786)
W/dalvikvm( 3373): Link of class 'Lcom/mycompany/mypackage/MainActivity;' failed
E/dalvikvm( 3373): Could not find class 'com.ping4.ping4alerts.MainActivity', referenced from method com.ping4.ping4alerts.tests.MainActivityInstrumentationTest.<init>
W/dalvikvm( 3373): VFY: unable to resolve const-class 3298 (Lcom/mycompany/mypackage/MainActivity;) in Lcom/mycompany/mypackage/tests/MainActivityInstrumentationTest;
rindress
  • 706
  • 1
  • 6
  • 12
  • Can you post the stack trace? – yogurtearl Aug 22 '14 at 01:45
  • Okay I updated the posting with the logcat output. I notice that there are a number of entries where the v7 support items are not resolved. I assume this is a big clue but I still can't find anything that helps. – rindress Aug 26 '14 at 16:54
  • It looks like if might have something to do with the way you are including the v7 and v4 support libraries. You should make sure that they are only included in your app and not in your Test APK. – yogurtearl Aug 26 '14 at 22:12
  • Thanks I appreciate you looking at it. I've added the dependencies that I have and I 'believe' that I've excluded the support and appcompat stuff. – rindress Aug 26 '14 at 22:22
  • What version of Android is this happening on? Are you using proguard? – yogurtearl Aug 27 '14 at 04:14
  • Also, for reference there is a similar stacktrace here: http://stackoverflow.com/questions/15014186/irreproducible-error-class-had-used-a-different-during-pre-verification – yogurtearl Aug 27 '14 at 04:14
  • I'm testing against a Genymotion image 4.4.2 and it's not using proguard. – rindress Aug 27 '14 at 13:18

3 Answers3

5

Okay so I was able to solve this problem based on a number of references. First thanks to yogurtearl for all you information. In essence there were a number of issues. In the end though the NoClassDefError was a red herring. The real issue was in the logcat output posted after the initial question. The indicated that there were issues trying to resolve thing after pre-dexing.

So I highly recommend people run the command gradle -q dependencies. Running this will give you a wealth of information. Based on that output I was able to determine that I was not excluding things so multiple versions were included creating an issue at runtime. The other thing that was incorrect initially was that I had exclude group: 'com.square.dagger' which was a typo. It should have been exclude group: 'com.squareup.dagger'. I hope that someone comes across this and it saves them some time trying to track down the issues. The following article was very useful in solving this issue: http://blog.gaku.net/multiple-dex-files-define-with-gradle/

rindress
  • 706
  • 1
  • 6
  • 12
  • THIS! Thank you so much. It took me several hours to figure out what was going on, but I just had to add some excludes to my build.gradle. – rrbrambley Oct 25 '16 at 21:35
3

Solutions:

  1. Change the dependency for fest-android to version 1.0.7

    androidTestCompile 'com.squareup:fest-android:1.0.7'

  2. Exclude support-v4 from fest-android:

    androidTestCompile ( 'com.squareup:fest-android:1.0.+' ) { exclude group:'com.android.support', module:'support-v4' }

  3. Upgrade to AssertJ-Android ( recommended ). Fest-Android has been superseded by AssertJ-Android ( http://square.github.io/assertj-android/ )

    androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'

Background info:

The problem is that "com.squareup:fest-android:1.0.+" is resolving to com.squareup:fest-android:1.0.8.

Version 1.0.8 includes a gradle dependency on 'com.android.support:support-v4:19.1.+'. See here: https://github.com/square/assertj-android/blob/1.0.8/build.gradle

This was translated to a "compile" scope dependency on support-v4 in the maven pom. See here: http://repo1.maven.org/maven2/com/squareup/fest-android/1.0.8/fest-android-1.0.8.pom

BTW, version 1.0.7 was built with Maven ( not gradle ) and has a "provided" scope dependency for support-v4, so that is why that behaves differently. See here: http://repo1.maven.org/maven2/com/squareup/fest-android/1.0.7/fest-android-1.0.7.pom

Also, Android Lint issues warnings for "Gradle Dynamic Version".

"Using + in dependencies lets you automatically pick up the latest available version rather than a specific, named version. However, this is not recommended; your builds are not repeatable; you may have tested with a slightly different version than what the build server used."

In this case, using a '+' for fest-android would have caused your build to break without any change on your part, when fest-android v1.0.8 was released.

yogurtearl
  • 3,035
  • 18
  • 24
  • So I made the changes that you suggested and I'm still getting the NoClassDefinedError? I removed fest and added assertj – rindress Sep 03 '14 at 13:48
0

I had a similar problem and I ended up figuring out that I was running up against the limitations of the multidex support library which I was using to get over Android's 65K method limit. There isn't really a good solution for that other than to try to rip out unused libs from your project, use proguard, or set your minSdkVersion to 21. Hopefully this helps anyone who ends up here facing a similar issue.

yuval
  • 6,369
  • 3
  • 32
  • 44