32

We are using PowerMock in few of our historical projects. Unfortunately PowerMock is quite dead and is not compatible with Java 11.

And we are using mockStatic(). Yes, we know its considered harmful - its in the legacy code and we would prefer not to rewrite those classes now...

Are there any options how to tweak PowerMock to support Java 11? Or is it possible to easily replace it with some other Java 11 compatible framework? (Mockito does not support mockStatic)

malejpavouk
  • 4,297
  • 6
  • 41
  • 67
  • 2
    Clicking that github link, it shows the last commit is 2 days ago ... – Kevin Van Dyck Oct 24 '18 at 10:44
  • 1
    Made by someone managing EasyMock integration most probably... The last release of powermock was more than year ago a patch release. Last minor more than 2 years ago. GitHub question about version 2 never responded to etc... – malejpavouk Oct 24 '18 at 10:56
  • 3
    As an aside: PowerMock is a powerful tool, but I would strongly recommend using it only as a weapon of last resort. If you can migrate away from needing to mock static members to a more testable design, you reduce your dependence on PowerMock and also make your code easier to maintain in the long term. – Daniel Pryden Oct 25 '18 at 12:56
  • Yeah, I totally agree. mockStatic() etc. is really a bad idea... – malejpavouk Oct 25 '18 at 13:45
  • 1
    2019-04-21: PowerMock 2.0.2 has been released, so not dead yet, feeling much better. It still doesn't support JUnit 5, though. – ThatAintWorking Jul 12 '19 at 18:58
  • java9 : https://stackoverflow.com/q/50456726/592355 – xerx593 Mar 13 '20 at 18:11

7 Answers7

26

After one year of no releases, things are really moving in PowerMock.

PowerMock 2.0.0-RC1 was released. And with PowerMockito 2.0.0-RC1 + @PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"})

The tests work under Java 11.

malejpavouk
  • 4,297
  • 6
  • 41
  • 67
  • I agree to all of what you said. Still, probably a helpful information for those who can't live without PowerMock. – GhostCat Oct 26 '18 at 10:43
  • 2
    That workaround appears to only have limited success. It doesn't work in many cases.
    See: https://github.com/powermock/powermock/issues/1061
    This one will also sometimes work:
    @PowerMockIgnore({"javax.net.ssl.*", "org.slf4j.*", "javax.parsers.*", "ch.qos.logback.*", "jdk.xml.internal.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
    – rakehell Sep 29 '20 at 22:44
17

Resolved with:

@PowerMockIgnore("jdk.internal.reflect.*")

Nothing else needed. You can put it on the top of the test class, with the other annotations, as in this example:

@RunWith(PowerMockRunner.class)
@PowerMockIgnore("jdk.internal.reflect.*")
@PrepareForTest({ File.class, FileSystemUtils.class })
public class MyTest {
   ...
}
Bruno Bossola
  • 1,128
  • 1
  • 13
  • 24
3

From mockito version 3.4.0 it is possible to mock static methods. You can refer to https://www.baeldung.com/mockito-mock-static-methods for more info.

2

If there are a lot of test classes to migrate to Java 11, it is possible to configure the ignores globally (only once in a configuration file): org/powermock/exntensions/configuration.properties

powermock.global-ignore=com.sun.org.apache.xerces.*,javax.xml.*,org.xml.*,org.w3c.*
Julian Broudy
  • 320
  • 3
  • 15
user327961
  • 2,440
  • 3
  • 22
  • 20
  • Note, spaces and double quotes are not allowed in the configuration.properties file. See: https://github.com/powermock/powermock/issues/989 – Navigatron Sep 28 '21 at 08:37
2

add the properties: org/powermock/extensions/configuration.properties

https://github.com/powermock/powermock/wiki/PowerMock-Configuration https://github.com/powermock/powermock-examples-maven/blob/master/global-ignore/src/test/resources/org/powermock/extensions/configuration.properties

e.g. for maven/gradle: src/test/resources/org/powermock/extensions/configuration.properties

powermock.global-ignore=javax.crypto.*,com.sun.xml.internal.stream.*,javax.xml.stream.*,javax.net.ssl.*,org.slf4j.*,javax.xml.parsers.*,ch.qos.logback.*,jdk.xml.internal.*,com.sun.org.apache.xerces.*,java.xml.*,org.xml.*,javax.management.*,org.w3c.dom.*
  • Note, spaces and double quotes are not allowed in the configuration.properties file. See: https://github.com/powermock/powermock/issues/989 – Navigatron Sep 28 '21 at 08:41
1

If use reflect in JDK11, you might see some warning like 'An illegal reflective access operation has occurred', because reflect JDK inner API is illegal since JDK9, still you can use it with a warning above.

To fix the problem temporary, try to use --add-exports or --add-opens in your argLing.

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

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>3.0.0-M5</version>
  <configuration>
    <argLine>
      @{argLine} --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED 
    </argLine>
  </configuration>
</plugin>

For more infomation, watch --add-opens introduce

jngcs
  • 11
  • 2
0

if your using java 11 then downgrade the dependency org.power.mock to 1.7.0.