You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reproducer Project
Instructions: run mvn clean install to see the error coming out of the ErrorReproducingTest class mockito-arquillian-issue-demo.zip
Code
@Test
public void invokeMockitoInsideArquillianTest() {
// This test is here to reproduce the error
Mockito.mock(ArrayList.class);
}
Description
As part of an upgrade from Java 11 to 21, I was in the middle of bumping up Mockito from 3.12.4 to 5.10.0. My team uses Arquillian with a Managed Wildfly container to execute integration tests. Typically devs blend in a little bit of mocking here and there to avoid problematic code they don't want to actually execute.
After the upgrade, we see that executing Mockito.mock(Foo.class) inside the integration test, throws an error:
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.util.Collections$3@555ec655
...
Caused by: java.lang.NoClassDefFoundError: org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher
I was able to get some background around this error from this older issue. I suspect that the key problem here is that Mockito ties to instantiate itself with a JBoss Classloader since it's inside the Wildfly container and not the bootstrap classloader as expected.
Note: the error reproducing project has an additionalMockito.mock(...); in the BaseArquillianTest.deployService(...) method which is responsible for packaging the WAR file and therefore runs "outside" the Wildfly container. No issues running it there!
We have a substantial body of integration tests which combine some usage of Mockito.mock(...) inside an Arquillian test and this is working at Mockito 3.12.4. It would be a substantial amount of refactoring if this is no longer possible to do with Mockito 5. I would appreciate if someone could come up with possible solution or workaround, thanks!
The text was updated successfully, but these errors were encountered:
Long version:
These lines of code in InlineDelegateButeBuddyMockMaker.java are responsible for reading a file named MockMethodDispatcher.raw, renaming it to MockMethodDispatcher.class and adding it to the classpath for the Bootstrap Class Loader. This initialization is all done at runtime when the first attempt to use a Mock occurs.
When these events are occurring in the context of a Wildfly container, the first class loader encountered is a JBoss Class Loader, and NOT the bootstrap class loader. This classloader has no awareness of the new class file just added to the boostrap class loader's classpath and we get a NoClassDefFoundError.
I tried artificially adding the renamed MockMethodDispatcher.class file to my WAR deployment in the hopes that the JBoss class loaders would then be able to find the class. Unfortunately, this attempt is detected by Mockito and we get an error message that Mockito requires that class to be loaded by the boostrap class loader specifically! You can see this error message here.
What finally worked for me is this directive added to jboss-deployment-structure.xml. That section is usually used to allow Wildfly access to internal JDK packages (e.g. "sun/reflect") and I reasoned that any package mentioned here would trigger a delegation by the JBoss class loader to the bootstrap class loader. Which is precisely what happened and everything started to work again!
Check that
Note that some configuration are impossible to mock via Mockito
(same as any question on stackoverflow.com)
Versions
Mockito: 5.10.0
Junit Jupiter: 5.10.1
JDK: OpenJDK 21.0.2
OS: MacOS Sonoma 14.4
Wildfly: 26.1.3.Final
Arquillian: 1.8.0.Final
Reproducer Project
Instructions: run
mvn clean install
to see the error coming out of theErrorReproducingTest
classmockito-arquillian-issue-demo.zip
Code
Description
As part of an upgrade from Java 11 to 21, I was in the middle of bumping up Mockito from 3.12.4 to 5.10.0. My team uses Arquillian with a Managed Wildfly container to execute integration tests. Typically devs blend in a little bit of mocking here and there to avoid problematic code they don't want to actually execute.
After the upgrade, we see that executing
Mockito.mock(Foo.class)
inside the integration test, throws an error:I was able to get some background around this error from this older issue. I suspect that the key problem here is that Mockito ties to instantiate itself with a JBoss Classloader since it's inside the Wildfly container and not the bootstrap classloader as expected.
Note: the error reproducing project has an additional
Mockito.mock(...);
in theBaseArquillianTest.deployService(...)
method which is responsible for packaging the WAR file and therefore runs "outside" the Wildfly container. No issues running it there!We have a substantial body of integration tests which combine some usage of Mockito.mock(...) inside an Arquillian test and this is working at Mockito 3.12.4. It would be a substantial amount of refactoring if this is no longer possible to do with Mockito 5. I would appreciate if someone could come up with possible solution or workaround, thanks!
The text was updated successfully, but these errors were encountered: