Search code examples
javatestingstaticfinalpowermock

PowerMock: java.lang.IllegalAccessError: java.lang.Class when mocking java.util.ServiceLoader


I am trying to mock the java ServicesLoader (which is final) in my tests with PowerMock, and it seems to fail...

The simplest test case that reproduces the error is this:

import java.util.ServiceLoader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ServiceLoader.class)
public class ServiceLoaderTest {
    @Test
    public void testServiceLoaderMock() {
        ServiceLoader mock = PowerMock.createMock(ServiceLoader.class);
    }
}

And the exception I get is:

-------------------------------------------------------------------------------
Test set: ServiceLoaderTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.407 sec <<< FAILURE!
testServiceLoaderMock(ServiceLoaderTest)  Time elapsed: 0.359 sec  <<< ERROR!
java.lang.IllegalAccessError: java.lang.Class
        at sun.reflect.GeneratedSerializationConstructorAccessor8.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:56)
        at org.powermock.reflect.internal.WhiteboxImpl.newInstance(WhiteboxImpl.java:257)
        at org.powermock.reflect.Whitebox.newInstance(Whitebox.java:139)
        at org.powermock.core.DefaultFieldValueGenerator.instantiateFieldType(DefaultFieldValueGenerator.java:74)
        at org.powermock.core.DefaultFieldValueGenerator.fillWithDefaultValues(DefaultFieldValueGenerator.java:51)
        at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2146)
        at org.powermock.api.easymock.PowerMock.createMock(PowerMock.java:98)
        at ServiceLoaderTest.testServiceLoaderMock(ServiceLoaderTest.java:12)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:322)
        at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
        at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:309)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:297)
        at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
        at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:222)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:161)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:135)
        at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
        at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
        at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:133)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:112)
        at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)

I guess it has something to do with doing some initialisation of the Class<T> field of the service, but I don't know for sure.

Once I have fixed this, I would like also to mock the static method ServiceLoader.load(Class) to return the previously created mock, so there might be more problems to come...

Any idea on how to solve it?


Solution

  • It seemed to be a bug. Got the answer from the mailing list:

    http://groups.google.com/group/powermock/browse_thread/thread/4afafbfdf1b3ce58