Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not initialize inline Byte Buddy mock maker. Linux JDK + Bazel + InlineMockMaker #1879

Closed
plaird opened this issue Feb 26, 2020 · 15 comments

Comments

@plaird
Copy link

plaird commented Feb 26, 2020

I don't have a reproducer to offer, and we could not narrow down the exact issue. But we ported a project from Maven -> Bazel build, and found that on some Linux systems (not all) we had test failures with:

  • java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
  • Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@2459333a
  • Caused by: org.mockito.exceptions.base.MockitoInitializationException:
    Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

These tests have the experimental Mockito InlineMockMaker enabled.

What we found was we could eliminate the error by marking the tests with the 'exclusive' tag in Bazel, which causes them to run serially not in parallel. The tests run fine in parallel on all Macs.

JDK for running tests:

  • Java : 1.8
  • JVM vendor name : Oracle Corporation
  • JVM vendor version : 25.162-b12
  • JVM name : Java HotSpot(TM) 64-Bit Server VM
  • JVM version : 1.8.0_162-b12
  • JVM info : interpreted mode OR mixed, we tried both
  • OS name : Linux

Other versions:

  • Bazel 1.0
  • Mockito Core: 3.1.0
  • ByteBuddy 1.10.6

Given the platform specific nature of this, we think this is a JDK issue not Mockito. But posting an issue just in case others hit the same.

Full stack:

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.$Proxy100.getHandler(Unknown Source)
at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:81)
at org.mockito.internal.util.DefaultMockingDetails.isMock(DefaultMockingDetails.java:32)
at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:106)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:81)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:69)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.afterTestMethod(ResetMocksTestExecutionListener.java:63)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:441)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at com.google.testing.junit.runner.internal.junit4.CancellableRequestFactory$CancellableRunner.run(CancellableRequestFactory.java:89)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at com.google.testing.junit.runner.junit4.JUnit4Runner.run(JUnit4Runner.java:112)
at com.google.testing.junit.runner.BazelTestRunner.runTestsInSuite(BazelTestRunner.java:153)
at com.google.testing.junit.runner.BazelTestRunner.main(BazelTestRunner.java:84)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@2459333a
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.(PluginRegistry.java:22)
at org.mockito.internal.configuration.plugins.Plugins.(Plugins.java:19)
at org.mockito.internal.util.MockUtil.(MockUtil.java:24)
at org.mockito.internal.util.DefaultMockingDetails.isMock(DefaultMockingDetails.java:32)
at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:106)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:81)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:69)
at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.beforeTestMethod(ResetMocksTestExecutionListener.java:56)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:289)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
... 19 more
Caused by: org.mockito.exceptions.base.MockitoInitializationException:
Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

@plaird
Copy link
Author

plaird commented Feb 26, 2020

Mockito team - feel free to close. I just wanted to flag this for other Bazel users, just in case they hit it too.

@TimvdLippe
Copy link
Contributor

Interesting, the stacktrace does not include the full details. We probably would need some more information as to why it could not initialize the inline mockmaker.

@raphw
Copy link
Member

raphw commented Feb 28, 2020

I assume that Bazle runs tests with some form of class loader isolation. In Java 8, it is not possible to attach to the same VM multiple times if reloading the tools.jar into the VM. This restriction was lifted in Java 9+ if you can update.

Alternatively, add the byte-buddy-agent.jar explicitly to your test VM processes as a Java agent. This should also give you a speedup since the dynamic attachment can be avoided alltogether.

@TimvdLippe
Copy link
Contributor

Closing this per the above comment. Thanks @raphw for the explanation and @plaird for getting this to our attention so that others can be helped when facing the same issue 😄

@shikhar
Copy link

shikhar commented Oct 6, 2020

Hmm, also ran into the same error with Bazel 3.3 and JDK11

...
Step #0 - "tests": Caused by: java.lang.reflect.InvocationTargetException
Step #0 - "tests": 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Step #0 - "tests": 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
Step #0 - "tests": 	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
Step #0 - "tests": 	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
Step #0 - "tests": 	at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:50)
Step #0 - "tests": 	... 39 more
Step #0 - "tests": Caused by: org.mockito.exceptions.base.MockitoInitializationException: 
Step #0 - "tests": Could not initialize inline Byte Buddy mock maker.
Step #0 - "tests": 
Step #0 - "tests": It appears as if your JDK does not supply a working agent attachment mechanism.
Step #0 - "tests": Java               : 11
Step #0 - "tests": JVM vendor name    : Azul Systems, Inc.
Step #0 - "tests": JVM vendor version : 11.0.6+10-LTS
Step #0 - "tests": JVM name           : OpenJDK 64-Bit Server VM
Step #0 - "tests": JVM version        : 11.0.6+10-LTS
Step #0 - "tests": JVM info           : mixed mode
Step #0 - "tests": OS name            : Linux
Step #0 - "tests": OS version         : 5.4.0-1025-gcp
...

Marking the tests relying on mockito-inline to be exclusive as a workaround

@ingomohr
Copy link

ingomohr commented Dec 4, 2020

@shikhar I was able to get this going (even on Java 8) with these dependencies:

	<dependencies>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>3.6.28</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-inline</artifactId>
			<version>3.6.28</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>net.bytebuddy</groupId>
			<artifactId>byte-buddy-agent</artifactId>
			<version>1.10.18</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>net.bytebuddy</groupId>
			<artifactId>byte-buddy</artifactId>
			<version>1.10.18</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

@mklueh
Copy link

mklueh commented Feb 22, 2021

I´m suddenly running into the same issue under Windows 10

It appears as if your JDK does not supply a working agent attachment mechanism.
Java               : 1.8
JVM vendor name    : Oracle Corporation
JVM vendor version : 25.221-b11
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0_221-b11
JVM info           : mixed mode
OS name            : Windows 10
OS version         : 10.0

using the following dependencies


testImplementation "org.junit.jupiter:junit-jupiter-params:5.7.1"
testImplementation "org.junit.jupiter:junit-jupiter-engine:5.7.1"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.1"
        
testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation 'org.mockito:mockito-junit-jupiter:3.7.7'
testImplementation 'org.mockito:mockito-inline:3.7.7'
testImplementation 'net.bytebuddy:byte-buddy-agent:1.10.20'
testImplementation 'net.bytebuddy:byte-buddy:1.10.20'

EDIT: The project contained an older version of JMockit 'org.jmockit:jmockit:1.24' which was clashing with mockit-inline. Removing JMockit entirely or upgrading it to 1.49 resolves the problem

@ram2012k
Copy link

I am facing the same issue with "mvn clean install " @mklueh

@jdai8
Copy link

jdai8 commented May 12, 2021

Thanks @plaird for creating this issue! I ran into the same issue while migrating from Gradle to Bazel. Adding the -javaagent pointing to byte buddy fixed it.

However, I'm still confused why this was not a problem for us in Gradle (and presumably it worked for you in Maven). I've double checked that we are using the same JDK, dependency versions, etc. with both build systems. We're also using the Junit platform to launch tests, which I believe is what Gradle does too. And I don't see Gradle starting tests with -javaagent. We're running tests in parallel in both cases as well.

Is it possible Gradle has some special handling for this issue? Or maybe Bazel's sandboxing on Linux affects things?

@raphw
Copy link
Member

raphw commented May 13, 2021

It might be the version resolution. What version of Byte Buddy is actually applied?

@jdai8
Copy link

jdai8 commented May 15, 2021

I've tried:

  • mockito-core 2.23.0, bytebuddy 1.10.13.
  • mockito-core 2.23.0, bytebuddy 1.9.10. This is known to work on Gradle.
  • mockito-core 2.23.0, bytebuddy 1.9.0. This version is declared in mockito's POM.
  • mockito-core 3.6.28, bytebuddy 1.10.18. As suggested above.

But none of these configurations worked.

The relevant part of the stack trace seems to be:

Caused by: org.mockito.exceptions.base.MockitoInitializationException:
Could not initialize inline Byte Buddy mock maker.

It appears as if your JDK does not supply a working agent attachment mechanism.
Java               : 1.8
JVM vendor name    : Amazon.com Inc.
JVM vendor version : 25.275-b01
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 1.8.0_275-b01
JVM info           : mixed mode
OS name            : Linux
OS version         : 4.4.0-210-generic

        at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<init>(InlineByteBuddyMockMaker.java:234)
        ... 92 common frames omitted
Caused by: java.lang.NullPointerException: null
        at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<clinit>(InlineByteBuddyMockMaker.java:118)
        ... 92 common frames omitted

@raphw
Copy link
Member

raphw commented May 17, 2021

It seems like ByteBuddyAgent.install() cannot be resolved. Have you tried to add byte-buddy-agent (on Maven Central) as a startup argument via -javaagent? This nullpointer is strange at this location, it should not be possible to have null returned from that method. Ideally, set some breakpoints to see why null is returned.

@fmeum
Copy link

fmeum commented Sep 19, 2021

This is likely caused by bazelbuild/bazel#3236, with the preferred workaround being to pass the option --sandbox_tmpfs_path=/tmp to Bazel, e.g. by adding the following line to .bazelrc:

test --sandbox_tmpfs_path=/tmp

This may increase RAM usage if tests write to /tmp rather than $TEST_TMPDIR, as recommended.

@nitinsethi86
Copy link

nitinsethi86 commented Oct 20, 2021

If you are seeing similar issue in mocking static methods in the Android world, you might need to do the following set of things. This is done only because JDK 8 and below don't allow multiple jars to be loaded as java agent.

  1. Add byte-buddy-agent.jar file downloaded from maven repository to your root project folder.
  2. Update gradle.properties file with the following JVM argument: org.gradle.jvmargs=-Djavaagent=byte-buddy-agent.jar
  3. Replace mockito-core test dependency with mockito-inline using the steps described here: How to set-up mockito-inline

@rdp
Copy link

rdp commented Feb 14, 2022

As a note this message:

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@401e3f5
Caused by: java.lang.reflect.InvocationTargetException
Caused by: org.mockito.exceptions.base.MockitoInitializationException: 

Could not initialize inline Byte Buddy mock maker.

It appears as if your JDK does not supply a working agent attachment mechanism.
Java               : 1.8
JVM vendor name    : Amazon.com Inc.
JVM vendor version : 25.312-b07
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 1.8.0_312-b07
JVM info           : mixed mode
OS name            : Linux
OS version         : 4.9.0-8-amd64

Caused by: java.lang.IllegalStateException: 

Mockito could not self-attach a Java agent to the current VM. This feature is required for inline mocking.
This error occured due to an I/O error during the creation of this agent: java.io.IOException: No such file or directory

Potentially, the current VM does not support the instrumentation API correctly
Caused by: java.io.IOException: No such file or directory

Was apparently caused by configuring the jvm with a "bad" tmpdir or something like that... (possibly one that didn't exist or what not). Kind of wish the exception message were better...

saraadams added a commit to EngFlow/bazel_invocation_analyzer that referenced this issue Dec 4, 2023
The Bazel flag `--incompatible_sandbox_hermetic_tmp` is added to fix
some issues with `mockito-core` and `byte-buddy`, e.g. see
https://github.com/EngFlow/bazel_invocation_analyzer/actions/runs/7067252322/job/19240379595?pr=151

See mockito/mockito#1879 for a similar issue
reported, and bazelbuild/bazel#3236 for the
"fix" by specifying `--incompatible_sandbox_hermetic_tmp`.
Note that this flag will be set to true by default with Bazel 7, which
is expected to be released next week.

---------

Signed-off-by: Sara Adams <sara.e.adams@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests