Skip to content

Execution with mockito-inline fails on platforms with EBCDIC as default encoding #2933

Closed

Description

@tobiasbaum

We recently switched from mockito-core to mockito-inline (specifically: org.mockito:mockito-inline:4.8.1). Since then, tests with mocks don't run on IBM z/OS (IBM JVM, Java 8) any more. Other platforms run fine. It seems like it has to do with the default encoding of the platform (Java property "file.encoding") being EBCDIC, which is not based on ASCII/UTF-8. Specifically, in the stacktrace below, the class name is "?[,/,ÁÊÑ>%Ñ>Á", which looks like an encoding issue.

After briefly skimming the Mockito source code, I think part of the problem is in org.mockito.internal.configuration.plugins.PluginFileReader, which uses IOUtil.readLines to convert a byte stream to strings. IOUtil.readLines then uses the default constructor of InputStreamReader, which uses the platform's default encoding. If the stream is by convention always in, e.g., UTF-8, the encoding should be specified explicitly. See https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html#dm-reliance-on-default-encoding-dm-default-encoding for more background information on this type of issue.

I can probably try some fixing myself, but wanted to post an issue first to give a chance for discussions.

Here's a stack trace:
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:84) at com.sun.proxy.$Proxy34.getHandler(Unknown Source) at org.mockito.internal.util.MockUtil.getMockHandlerOrNull(MockUtil.java:158) at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:147) at org.mockito.internal.configuration.injection.scanner.MockScanner.isMockOrSpy(MockScanner.java:83) at org.mockito.internal.configuration.injection.scanner.MockScanner.preparedMock(MockScanner.java:71) at org.mockito.internal.configuration.injection.scanner.MockScanner.scan(MockScanner.java:59) at org.mockito.internal.configuration.injection.scanner.MockScanner.addPreparedMocks(MockScanner.java:45) at org.mockito.internal.configuration.InjectingAnnotationEngine.injectCloseableMocks(InjectingAnnotationEngine.java:112) at org.mockito.internal.configuration.InjectingAnnotationEngine.processInjectMocks(InjectingAnnotationEngine.java:61) at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:48) at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:81) at org.mockito.internal.framework.DefaultMockitoSession.<init>(DefaultMockitoSession.java:43) at org.mockito.internal.session.DefaultMockitoSessionBuilder.startMocking(DefaultMockitoSessionBuilder.java:83) at de.set.posy.workplace.plugins.poolOperator.gwt.server.poolContent.PoolContentTableServiceImplTest.setUp(PoolContentTableServiceImplTest.java:39) at de.setsoftware.junit.SETTestcaseRunner$SetUpTearDownRule$1.invokeIfPresent(SETTestcaseRunner.java:155) at de.setsoftware.junit.SETTestcaseRunner$SetUpTearDownRule$1.evaluate(SETTestcaseRunner.java:144) at de.setsoftware.junit.SETTestcaseRunner.runChild(SETTestcaseRunner.java:58) at de.setsoftware.junit.SETTestcaseRunner.runChild(SETTestcaseRunner.java:24) at de.setsoftware.junit.SETSuiteRunner.run(SETSuiteRunner.java:193) at de.setsoftware.UnitTestRunner.main(UnitTestRunner.java:127) Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.ClassLoader$CompoundEnumeration@c88de7f9 at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:56) at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:65) at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:50) at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:27) at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:22) at org.mockito.internal.MockitoCore.<clinit>(MockitoCore.java:73) at org.mockito.Mockito.<clinit>(Mockito.java:1647) at de.set.posy.workplace.plugins.poolOperator.gwt.server.poolContent.PoolContentTableServiceImplTest.setUp(PoolContentTableServiceImplTest.java:36) Caused by: java.lang.ClassNotFoundException: _?[,_/,ÁÊÑ>%Ñ>Á at java.net.URLClassLoader.findClass(URLClassLoader.java:610) at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:945) at java.lang.ClassLoader.loadClass(ClassLoader.java:890) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:873) at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:50)

check that

  • The mockito message in the stacktrace have useful information, but it didn't help
  • The problematic code (if that's possible) is copied here; N/A, problem is largely independent of the tested code
  • Provide versions (mockito / jdk / os / any other relevant information)
  • Provide a Short, Self Contained, Correct (Compilable), Example of the issue: N/A, is likely a platform issue independent of the code. I hope my description above helps anyway. And as soon as I'll have a running version, I can do testing on z/OS.
  • Read the contributing guide

Activity

  1. TimvdLippe commented on Mar 8, 2023

    @TimvdLippe
    Contributor

    Good catch! Yes we should make the encoding explicit. Happy to accept a PR for this!

  2. added a commit that references this issue on Sep 29, 2024
    fc136e4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions