powermock: Powermock 2.0.0-beta.5 problem with jdk9 modules

What steps will reproduce the problem?

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;

import javax.xml.parsers.DocumentBuilderFactory;

@RunWith(PowerMockRunner.class)
public class TestClass {
    private static final String XINCLUDE_FIXUP_BASE_URIS = "http://apache.org/xml/features/xinclude/fixup-base-uris";

    @Test
    public void test() throws Exception {
        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setFeature(XINCLUDE_FIXUP_BASE_URIS, true);
    }
}

What is the expected output?

This code/test should be executed without exceptions

What do you see instead?

No @RunWith(PowerMockRunner.class) runner + jdk8/9 - works fine powermock 1.7.3/2.0.0-beta.5 + jdk8 - works fine powermock 2.0.0-beta.5 + jkd9: Causes problem with module access inside JDK, likely as a result of classloading modifications, while there is nothing except calling jdk classes and enabling powermock runner here:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.powermock.reflect.internal.WhiteboxImpl (file:/Users/dmitry/.m2/repository/org/powermock/powermock-reflect/2.0.0-beta.5/powermock-reflect-2.0.0-beta.5.jar) to method java.lang.Object.finalize()
WARNING: Please consider reporting this to the maintainers of org.powermock.reflect.internal.WhiteboxImpl
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

java.lang.IllegalAccessError: class com.sun.org.apache.xerces.internal.parsers.XML11Configuration (in unnamed module @0x229f66ed) cannot access class jdk.xml.internal.JdkXmlUtils (in module java.xml) because module java.xml does not export jdk.xml.internal to unnamed module @0x229f66ed

	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.<init>(XML11Configuration.java:535)
	at com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration.<init>(XIncludeAwareParserConfiguration.java:130)
	at com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration.<init>(XIncludeAwareParserConfiguration.java:91)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.<init>(DOMParser.java:144)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.<init>(DOMParser.java:128)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.<init>(DocumentBuilderImpl.java:138)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.<init>(DocumentBuilderImpl.java:131)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl.setFeature(DocumentBuilderFactoryImpl.java:210)
	at com.spikhalskiy.TestClass.test(TestClass.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
	at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
	at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
	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:136)
	at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)
	at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
	at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)

What version of the product are you using? This problem exists with powermock 2.0.0-beta.5 and jdk 9 / 9.0.1

Workaround This could be hotfixed by passing

--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED

for tests, for example in maven-surefire-plugin. But it’s not how things should work and it shouldn’t be a permanent solution.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 10
  • Comments: 20 (3 by maintainers)

Commits related to this issue

Most upvoted comments

@naveensharma18 I just fixed with @PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"})

@matitalatina’s comment helped me, but I had one test that also required me to ignore org.w3c.dom.* as well. Just wanted to add it to the list in case it helps others:

@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"})

This error is also present for our project: Powermock 2.0.4 and java 11

Fixed in all tests by creating configuration.properties file in test/resources/org/powermock/extensions/ with content below:

powermock.global-ignore=javax.xml.parsers.*,org.apache.xerces.jaxp.*,com.sun.org.apache.xerces.*,org.xml.*

NB: Comma separation and NO spaces in the property value, otherwise it will not work!

@attila123, thank you for correcting the file path, I’ve updated it in this post

It seems that I had to add com.sun.org.apache.xalan.* as well.

@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*"})

I was able to get past this by upgrading my java version to the latest java 11. I was using the binaries from 2018

$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

I upgraded the java version to the latest and it seemed to fix my problem

$ java --version
openjdk 11.0.6 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1, mixed mode, sharing)

Is there any updated information about this issue? When is this problem with java 9 expected to be fixed? In worst case scenario we are forced in our team, to remove Powermock in our project completely if this is not fixed in a near future.

I also agree that still supporting java 6 fells unnecessary. Nobody can expect that new Powermock version still should support that old JDK versions

Are users still using JDK 6? It seems like JDK 7 is the minimum these days and most projects are migrating to JDK 8.

@jbrokamp Thanks for the suggestion, a small correction though: looks like one needs to create test/resources/org/powermock/extensions/configuration.properties rather than test/resources/configuration.properties. The package name is as per powermock documentation https://github.com/powermock/powermock/wiki/PowerMock-Configuration

The same issue exists with JDK11 modules. Details: Powermock version: 2.0.0

Caused by: org.mockito.exceptions.misusing.InjectMocksException: .........................
Caused by: java.lang.IllegalAccessError: class javax.xml.parsers.FactoryFinder (in unnamed module @0x5da7cee2) cannot access class jdk.xml.internal.SecuritySupport (in module java.xml) because module java.xml does not export jdk.xml.internal to unnamed module @0x5da7cee2
	at javax.xml.parsers.FactoryFinder.<clinit>(FactoryFinder.java:69)
	at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:147)
.....................
.........................
..........................

@PowerMockIgnore({“com.sun.org.apache.xerces.", "javax.xml.”, “org.xml.", "org.w3c.”}) is helping with above issue

@Spikhalskiy As you suggested I’ve used both @PowerMockIgnore({ “com.sun.org.apache.xerces.", "javax.xml.parsers.”}) but still I’m getting following issue.

java.lang.LinkageError: loader constraint violation: when resolving method “javax.xml.parsers.SAXParser.parse(Lorg/xml/sax/InputSource;Lorg/xml/sax/helpers/DefaultHandler;)V” the class loader (instance of org/powermock/core/classloader/MockClassLoader) of the current class, ch/qos/logback/core/joran/event/SaxEventRecorder, and the class loader (instance of <bootloader>) for the method’s defining class, javax/xml/parsers/SAXParser, have different Class objects for the type org/xml/sax/InputSource used in the signature

P.S. : I’m using Java 10.0.1 + org.powermock:powermock-api-mockito2:2.0.0-beta.5 +org.powermock:powermock-module-junit4:2.0.0-beta.5

Thank you for the finding the issue. I think, I figure out the main clause of the exception. PowerMock classloader reloads XML11Configuration but without specifying module/or ignore module of the class. As result the unnamed module is autogenerated. I can suggest another workaround. If it works then my guess is correct. Could you try to use @PowerMockIgnore("com.sun.org.apache.xerces.*")

It seems that I had to add com.sun.org.apache.xalan.* as well.

@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*"})

Run into the same issue and this did it for me. Thanks for the workaround, but still hope we can get a fix for this.

@Spikhalskiy I have idea what is going on and a thought how to fix the issue.

The issue is with loading classes from modules. PowerMock has a custom classloader. But the classloader knows nothing about modules in Java9 and loads all classes as it was in previous version. As result even if a class from a named module it will be loaded with unnamed module.

The main difficult with a fix it is keep comb ability with jdk6. I will have to use classes from Java9, so it means I will be forced to either have additional modules for Java9 or use Multi-Release jars. I’m not going to do it in PowerMock 2. I’d like to focus on two left features to release at first, make release and then start working on modularity in Java9