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
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