Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of "Could not initialize plugin: interface org.mockito.plugins.MockMaker" when launching JUnit with Mockito using OpenJDK 12

I've been migrating a project from Java 8 to Java 12. Everything went well except for unit tests. When I compile and launch tests with Maven, many tests fail with the following message:

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
    at com.tetratech.csoft.ui.jfx.AppContextTest.<init>(AppContextTest.java:22)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.CompoundEnumeration@35fd987b
Caused by: org.mockito.exceptions.base.MockitoInitializationException: 

Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

Java               : 12
JVM vendor name    : Oracle Corporation
JVM vendor version : 12+33
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 12+33
JVM info           : mixed mode, sharing
OS name            : Windows 10
OS version         : 10.0

Caused by: java.lang.IllegalStateException: Could not self-attach to current VM using external process

When lauched from IntelliJ, I get a more detailed message:

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 com.sun.proxy.$Proxy7.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:1907)
    at org.mockito.Mockito.mock(Mockito.java:1816)
    at com.tetratech.csoft.ui.jfx.AppContextTest.<init>(AppContextTest.java:22)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
    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.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.CompoundEnumeration@460d0a57
    at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:54)
    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.util.MockUtil.<clinit>(MockUtil.java:24)
    ... 29 more
Caused by: org.mockito.exceptions.base.MockitoInitializationException: 
Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

Java               : 12
JVM vendor name    : Oracle Corporation
JVM vendor version : 12+33
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 12+33
JVM info           : mixed mode, sharing
OS name            : Windows 10
OS version         : 10.0

To solve this, as suggested as answers to similar problems, I modified pom.xml to include the following dependancies:

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.25.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>2.25.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.9.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
            <version>1.9.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.objenesis</groupId>
            <artifactId>objenesis</artifactId>
            <version>3.0.1</version>
            <scope>test</scope>
        </dependency>

According to some people, this is the kind of problem that occurs when launching tests with a JRE instead of a JDK. Since I'm using OpenJDK 12, this is not the case.

Tests failing in OpenJDK 12 used to run successfully in Java 8. There were no modifications other than the ones I've shown you. org.mockito.plugins.MockMaker is required in our tests because many classes come from legacy code, with a lot of final classes. And as you can see in the message log, tests are launched with OpenJDK 12 running on Windows 10.

Is there any way to run these tests with Mockito? I know that PowerMockito can probably solve this problem, but using it means a lot of modifications in test classes.

Thanks.

like image 204
Francois Avatar asked Apr 03 '19 21:04

Francois


1 Answers

I've finally been able to solve my problem. The key to the answer is the line

java.lang.IllegalStateException: Could not self-attach to current VM using external process

For Java 9 and more, one must add -Djdk.attach.allowAttachSelf=true as VM argument to avoid this exception. When I did, unit tests ran perfectly.

Here are the links where I've found this :

https://github.com/raphw/byte-buddy/issues/612

https://github.com/mockk/mockk/issues/254

like image 142
Francois Avatar answered Nov 04 '22 16:11

Francois