NoClassDefFoundError while running unit tests with Roboelectric 3.8

老子叫甜甜 提交于 2019-12-08 19:42:12

问题


My Android project has several modules (one application and multiple libraries) and when I try to run all the unit tests (Robolectric 3.8) from the command line

./gradlew testDebugUnitTest

I get the following error (not when I run the same task from Android Studio)

java.lang.NoClassDefFoundError: android/content/Context at java.base/java.lang.Class.getDeclaredConstructors0(Native Method) at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3110) at java.base/java.lang.Class.getConstructor0(Class.java:3315) at java.base/java.lang.Class.getConstructor(Class.java:2108) at org.robolectric.RobolectricTestRunner.getHooksInterface(RobolectricTestRunner.java:473) at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:308) at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:241) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:123) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:77) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) at com.sun.proxy.$Proxy1.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:108) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) at java.base/java.lang.Thread.run(Thread.java:844) Caused by: java.lang.ClassNotFoundException: couldn't load android.content.Context at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:174) at org.robolectric.internal.bytecode.SandboxClassLoader.lambda$findClass$0(SandboxClassLoader.java:133) at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50) at org.robolectric.internal.bytecode.SandboxClassLoader.findClass(SandboxClassLoader.java:132) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:563) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) ... 45 more Caused by: java.lang.IllegalArgumentException at org.objectweb.asm.ClassReader.(Unknown Source) at org.objectweb.asm.ClassReader.(Unknown Source) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.isOverridingFinalMethod(SandboxClassLoader.java:502) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.instrumentInheritedObjectMethod(SandboxClassLoader.java:523) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.instrument(SandboxClassLoader.java:395) at org.robolectric.internal.bytecode.SandboxClassLoader$InvokeDynamicClassInstrumentor.instrument(SandboxClassLoader.java:1274) at org.robolectric.internal.bytecode.SandboxClassLoader.getInstrumentedBytes(SandboxClassLoader.java:271) at org.robolectric.internal.bytecode.SandboxClassLoader.lambda$maybeInstrumentClass$1(SandboxClassLoader.java:166) at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50) at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:165) ... 50 more

The build.gradle file on each module contains the following configuration

testOptions {
    unitTests {
        returnDefaultValues true
    }
}

The application module defines a couple of flavours all running in the same dimension

flavorDimensions 'default'

Any idea?


回答1:


I have that kind of (not same)error before. I think NoClassDefFoundError is telling you that your Android application is running on a different version of android like 32bit or 64 bit you need to add jniLibs folder in the android project.

That get your library according to a device at runtime.

Search about JniLibs about more.

Thanks!!




回答2:


It has to be with your dependencies. You have to put the dependencies you use with testImplementation.

For example, I was getting the error having this dependency defined:

compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"

Now I've added the other one:

//Used to compile
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"
//Used to compile tests
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"

Check what dependency you are missing running

./gradlew test --stacktrace

Gradle will automatically generate html with all the trace organized.

It's just a possibility, let me know if it works.

UPDATE: This work only if you use compileOnly with the missed dependencies. The reason is that compileOnly declares dependencies only used at compilation time, so we need testImplementation also. Another solution would be to directly use implementation which would add the requires dependencies (so we wouldn't need testImplementation).



来源:https://stackoverflow.com/questions/50985554/noclassdeffounderror-while-running-unit-tests-with-roboelectric-3-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!