linkedin / dexmaker

A utility for doing compile or runtime code generation targeting Android's Dalvik VM
Apache License 2.0
1.86k stars 248 forks source link

Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeratio #183

Open adrienrx opened 2 years ago

adrienrx commented 2 years ago

Hello,

I am getting an issue when trying to use anything mock related in instrumented test.

AndroidJUnitRunner is default 'testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"'

androidTestImplementation config

    androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3'
    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.3'
    androidTestImplementation 'androidx.work:work-testing:2.7.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
    androidTestImplementation 'androidx.test.ext:truth:1.4.0'
    androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'

jvm is 1.8 + coreLibDesugar up compileSdk is 31 minSdk is 26

I have tried to run tests with AndroidJunit4::class / MockitoJUnitRunner::class / even without a RunWIth (was getting a bit desperate)/

I'm seeing quite a lot of similar issues online.

org.mockito.exceptions.base.MockitoException: 
Failed to release mocks

This should not happen unless you are using a third-party mock maker
    at REDACTED
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:76)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:444)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2218)
Caused by: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
    at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:88)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy11.isTypeMockable(Unknown Source)
    at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:33)
    at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
    at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:261)
    at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:234)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:94)
    at org.mockito.Mockito.mock(Mockito.java:1981)
    at org.mockito.internal.configuration.MockAnnotationProcessor.processAnnotationForMock(MockAnnotationProcessor.java:71)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:28)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:25)
    at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:44)
    at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:72)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:73)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:47)
    at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:81)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:99)
    at REDACTED
    at java.lang.reflect.Method.invoke(Native Method)
    ... 26 more
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@3b307d9
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:58)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:69)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:54)
    at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:28)
    at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:22)
    at org.mockito.internal.configuration.plugins.Plugins.getAnnotationEngine(Plugins.java:69)
    at org.mockito.internal.configuration.GlobalConfiguration.tryGetPluginAnnotationEngine(GlobalConfiguration.java:50)
    at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:80)
    ... 29 more
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:53)
    ... 36 more
Caused by: org.mockito.exceptions.base.MockitoInitializationException: 
Could not initialize inline Byte Buddy mock maker.

It appears as if you are trying to run this mock maker on Android which does not support the instrumentation API.

IMPORTANT INFORMATION FOR ANDROID USERS:

The regular Byte Buddy mock makers cannot generate code on an Android VM!
To resolve this, please use the 'mockito-android' dependency for your application:
https://search.maven.org/artifact/org.mockito/mockito-android

Java               : 0.9
JVM vendor name    : The Android Project
JVM vendor version : 2.1.0
JVM name           : Dalvik
JVM version        : 0.9
JVM info           : null
OS name            : Linux
OS version         : 4.4.177-22723052

    at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.<init>(InlineDelegateByteBuddyMockMaker.java:244)
    at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<init>(InlineByteBuddyMockMaker.java:23)
    ... 39 more
Caused by: java.lang.IllegalStateException: Failed to access VM name via management factory
    at net.bytebuddy.agent.ByteBuddyAgent$ProcessProvider$ForCurrentVm$ForLegacyVm.resolve(ByteBuddyAgent.java:1336)
    at net.bytebuddy.agent.ByteBuddyAgent$ProcessProvider$ForCurrentVm.resolve(ByteBuddyAgent.java:1311)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:611)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:563)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:540)
    at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.<clinit>(InlineDelegateByteBuddyMockMaker.java:115)
    ... 40 more
Caused by: java.lang.ClassNotFoundException: java.lang.management.ManagementFactory
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:454)
    at java.lang.Class.forName(Class.java:379)
    at net.bytebuddy.agent.ByteBuddyAgent$ProcessProvider$ForCurrentVm$ForLegacyVm.resolve(ByteBuddyAgent.java:1333)
    ... 45 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.management.ManagementFactory" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/system/framework/android.test.base.jar", zip file "/data/app/~~YKcKaVHNOa7__I0rFd2iQA==/REDACTED.test-qKa2xIJo2Sks_E7Kg7k3-w==/base.apk", zip file "/data/app/~~3GiuANUVt8bg9l8WPsCE-g==/nREDACTED-Twb-54oU2--tQSyby1_2-g==/base.apk"],nativeLibraryDirectories=[/data/app/~~YKcKaVHNOa7__I0rFd2iQA==/REDACTED.test-qKa2xIJo2Sks_E7Kg7k3-w==/lib/arm64, /data/app/~~3GiuANUVt8bg9l8WPsCE-g==/REDACTED-Twb-54oU2--tQSyby1_2-g==/lib/arm64, /data/app/~~YKcKaVHNOa7__I0rFd2iQA==/nREDACTED.test-qKa2xIJo2Sks_E7Kg7k3-w==/base.apk!/lib/arm64-v8a, /data/app/~~3GiuANUVt8bg9l8WPsCE-g==/REDACTED-Twb-54oU2--tQSyby1_2-g==/base.apk!/lib/arm64-v8a, /system/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    ... 49 more

When using a different set of dependencies, the error changes..

    debugImplementation 'androidx.fragment:fragment-testing:1.5.2'

    androidTestImplementation "androidx.test:core:1.4.0"
    androidTestImplementation 'androidx.test:runner:1.4.0'
    androidTestImplementation 'androidx.test:rules:1.4.0'
    androidTestImplementation "androidx.test.ext:junit-ktx:1.1.3"
    androidTestImplementation 'androidx.work:work-testing:2.7.1'
    androidTestImplementation 'androidx.test.ext:truth:1.4.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
    androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.3"
    androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
    at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy13.isTypeMockable(Unknown Source)
    at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
    at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
    at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:240)
    at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:228)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:61)
    at org.mockito.Mockito.mock(Mockito.java:1908)
    at org.mockito.internal.configuration.MockAnnotationProcessor.processAnnotationForMock(MockAnnotationProcessor.java:44)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:19)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
    at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:38)
    at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:62)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:49)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:41)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:69)
    at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:43)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:74)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:80)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:444)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2218)
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/tools/ToolProvider;
    at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<init>(InlineByteBuddyMockMaker.java:170)
    at java.lang.Class.newInstance(Native Method)
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:49)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:57)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:44)
    at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:22)
    at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:19)
    at org.mockito.internal.configuration.plugins.Plugins.getMockitoLogger(Plugins.java:66)
    at org.mockito.internal.runners.RunnerFactory$2.get(RunnerFactory.java:42)
    at org.mockito.internal.runners.RunnerFactory$2.get(RunnerFactory.java:40)
    at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:40)
    ... 26 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.tools.ToolProvider" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/system/framework/android.test.base.jar", zip file "/data/app/~~B22MdhwkjDWTIavspaJNLg==/REDACTED.test-EBd3z8Z437Vq9jy4mgegnw==/base.apk", zip file "/data/app/~~OHg9IelkHvvayhPqGeeUTQ==/nREDACTED-gaDSe_1qSCgegUM4xUxaPw==/base.apk"],nativeLibraryDirectories=[/data/app/~~B22MdhwkjDWTIavspaJNLg==/REDACTED.test-EBd3z8Z437Vq9jy4mgegnw==/lib/arm64, /data/app/~~OHg9IelkHvvayhPqGeeUTQ==/REDACTED-gaDSe_1qSCgegUM4xUxaPw==/lib/arm64, /data/app/~~B22MdhwkjDWTIavspaJNLg==/REDACTED.test-EBd3z8Z437Vq9jy4mgegnw==/base.apk!/lib/arm64-v8a, /data/app/~~OHg9IelkHvvayhPqGeeUTQ==/REDACTED-gaDSe_1qSCgegUM4xUxaPw==/base.apk!/lib/arm64-v8a, /system/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    ... 37 more
drewhannay commented 2 years ago

As stated in the README, the dexmaker-mockito-inline artifact can only be used on Android P (API 28) and above. The underlying system capabilities to mock static and final code does not exist before that API level.

If you are running on Android 4.4, you should use the regular dexmaker-mockito artifact instead.

adrienrx commented 2 years ago

@drewhannay Are you refering to OS version : 4.4.177-22723052 That's probably referring to my workstation OS, not android. I'm not running 4.4

adrienrx commented 2 years ago

image

That would be the kernel verison of the phone I'm running the test on.

Starting in Android "P", it is possible to mock final classes and methods using the dexmaker-mockito-inline library. If you execute your tests on a device or emulator running Android P or above

I don't think I'm breaking the readme recommendation. Am I?

drewhannay commented 2 years ago

Ah, my apologies. Usually this is the error you get when running on a too old Android version, and I saw 4.4 and assumed 😅

The other thing to check: Do you have any other mockito dependencies in the androidTestImplementation? Maybe being pulled in transitively through some other dependency? Running ./gradlew :yourModule:androidDependencies should show you the full graph.

adrienrx commented 2 years ago

I'm currently OOO - I'll be updating this ticket on the 07/09. Please don't close