【问题标题】:Running tests using gradle or inside android studio result in NoClassDefFoundError使用 gradle 或在 android studio 中运行测试会导致 NoClassDefFoundError
【发布时间】:2015-08-21 07:46:04
【问题描述】:

但是,我知道问这种没有具体细节的问题是非常困难的;有问题的项目是专有的,我无法在任何其他项目中重现该问题。

所以我在 build.gradle 文件中添加了以下内容:

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'
}

我也定义了两种产品风味,但都不起作用。我的测试类是:

   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);
        }
    }

现在在工作室中,它发现 MainActivity.class 很好,并添加了正确的导入。然而;当我运行测试时,构造函数会抛出一个异常,即找不到 .class 的完全限定路径。我试过用--debug 运行gradle,我没有看到任何异常。生成的 apk 文件有一个 classes.dex 并使用 dex2jar 我在那里看到 MainActivity.class。所以此时对于为什么在测试执行过程中找不到类文件有点茫然。有没有人有任何其他方法可以尝试调试这种情况,就像我说我有其他项目工作得很好,但我无法修改它们以显示这种行为。

我们将不胜感激。

编辑:来自 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

编辑:build.gradle 依赖项

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'
    }
}

更新: 更新依赖项后,我仍然得到 NoClassDefFoundError 并且在 logcat 中我看到了

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;

【问题讨论】:

  • 你能发布堆栈跟踪吗?
  • 好的,我用 logcat 输出更新了帖子。我注意到有许多条目未解决 v7 支持项。我认为这是一个很大的线索,但我仍然找不到任何有用的东西。
  • 看起来可能与您包含 v7 和 v4 支持库的方式有关。您应确保它们仅包含在您的应用中,而不包含在您的测试 APK 中。
  • 谢谢,感谢您的关注。我已经添加了我拥有的依赖项,并且我“相信”我已经排除了支持和 appcompat 的东西。
  • 这是在哪个版本的 Android 上发生的?你在用proguard吗?

标签: android android-studio android-gradle-plugin android-espresso


【解决方案1】:

好的,所以我能够根据大量参考资料解决这个问题。首先感谢 yogurtearl 提供的所有信息。本质上存在许多问题。最后,尽管 NoClassDefError 是一个红鲱鱼。真正的问题是在最初的问题之后发布的 logcat 输出。表示在预索引后尝试解决问题时出现问题。

所以我强烈建议人们运行命令gradle -q dependencies。运行此程序将为您提供丰富的信息。基于该输出,我能够确定我没有排除事物,因此包含多个版本,在运行时创建了一个问题。最初不正确的另一件事是我有exclude group: 'com.square.dagger',这是一个错字。应该是exclude group: 'com.squareup.dagger'。我希望有人能遇到这个问题,这样可以节省他们一些时间来寻找问题。以下文章对解决此问题非常有用:http://blog.gaku.net/multiple-dex-files-define-with-gradle/

【讨论】:

  • 这个!太感谢了。我花了几个小时才弄清楚发生了什么,但我只需要在我的 build.gradle 中添加一些排除项。
【解决方案2】:

解决方案:

  1. 将 fest-android 的依赖更改为 1.0.7 版本

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

  2. 从 fest-android 中排除 support-v4:

    androidTestCompile('com.squareup:fest-android:1.0.+'){ 排除组:'com.android.support',模块:'support-v4' }

  3. 升级到 AssertJ-Android(推荐)。 Fest-Android 已被 AssertJ-Android (http://square.github.io/assertj-android/) 取代

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

背景信息:

问题是“com.squareup:fest-android:1.0.+”正在解析为 com.squareup:fest-android:1.0.8。

1.0.8 版包含对“com.android.support:support-v4:19.1.+”的 gradle 依赖项。见这里:https://github.com/square/assertj-android/blob/1.0.8/build.gradle

这被翻译成对 maven pom 中 support-v4 的“编译”范围依赖。见这里:http://repo1.maven.org/maven2/com/squareup/fest-android/1.0.8/fest-android-1.0.8.pom

顺便说一句,版本 1.0.7 是 built with Maven (不是 gradle )并且对 support-v4 具有“提供的”范围依赖性,所以这就是行为不同的原因。见这里:http://repo1.maven.org/maven2/com/squareup/fest-android/1.0.7/fest-android-1.0.7.pom

此外,Android Lint 会针对 "Gradle Dynamic Version" 发出警告。

“在依赖项中使用+ 可以让您自动选择最新的可用版本,而不是特定的命名版本。但是,不建议这样做;您的构建不可重复;您可能使用与之前稍有不同的版本进行测试构建服务器使用了什么。”

在这种情况下,当 fest-android v1.0.8 发布时,对 fest-android 使用“+”会导致您的构建中断,而您没有进行任何更改。

【讨论】:

  • 所以我按照您的建议进行了更改,但仍然收到 NoClassDefinedError?我删除了 fest 并添加了 assertj
【解决方案3】:

我遇到了类似的问题,我最终发现我遇到了limitations of the multidex support library,我用它来克服 Android 的 65K 方法限制。除了尝试从项目中删除未使用的库、使用 proguard 或将 minSdkVersion 设置为 21 之外,没有真正好的解决方案。希望这对最终遇到类似问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    相关资源
    最近更新 更多