Mockito,Java 9和java.lang.ClassNotFoundException:sun.reflect.ReflectionFactory

我的项目是Wildfly 13应用程序,它使用Mockito测试库。 该应用程序不使用Java 9模块结构。 只要服务器在Java 8上运行,测试工作正常,但是一旦我们升级到Java 9,它们就会失败并出现以下exception:

org.objenesis.ObjenesisException: java.lang.ClassNotFoundException: sun.reflect.ReflectionFactory from [Module "test.war" from Service Module Loader] at test.war//org.objenesis.instantiator.sun.SunReflectionFactoryHelper.getReflectionFactoryClass(SunReflectionFactoryHelper.java:63) at test.war//org.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(SunReflectionFactoryHelper.java:37) at test.war//org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.(SunReflectionFactoryInstantiator.java:41) at test.war//org.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(StdInstantiatorStrategy.java:68) at test.war//org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:94) at test.war//org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73) at test.war//org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19) at test.war//org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47) at test.war//org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25) at test.war//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35) at test.war//org.mockito.internal.MockitoCore.mock(MockitoCore.java:68) at test.war//org.mockito.Mockito.mock(Mockito.java:1895) at test.war//org.mockito.Mockito.mock(Mockito.java:1804) at test.war//application code... 

我尝试了各种选项和组合:

  • 使用Java 8,9,10进行编译
  • 运行最新版本的OpenJDK 9和10
  • 设置编译器和vm选项–add-modules jdk.unsupported和–add-exports jdk.unsupported / sun.reflect = ALL-UNNAMED“

总是一样的错误。 我没有想法。

--show-module-resolution

 root jdk.javadoc jrt:/jdk.javadoc root jdk.jdi jrt:/jdk.jdi root jdk.jshell jrt:/jdk.jshell root jdk.sctp jrt:/jdk.sctp root jdk.xml.dom jrt:/jdk.xml.dom root jdk.jsobject jrt:/jdk.jsobject root jdk.unsupported jrt:/jdk.unsupported root jdk.scripting.nashorn jrt:/jdk.scripting.nashorn root jdk.httpserver jrt:/jdk.httpserver root jdk.management jrt:/jdk.management root jdk.net jrt:/jdk.net root jdk.security.auth jrt:/jdk.security.auth root jdk.dynalink jrt:/jdk.dynalink root java.se jrt:/java.se root jdk.compiler jrt:/jdk.compiler root jdk.accessibility jrt:/jdk.accessibility root jdk.jartool jrt:/jdk.jartool root jdk.jconsole jrt:/jdk.jconsole root jdk.attach jrt:/jdk.attach root jdk.security.jgss jrt:/jdk.security.jgss jdk.security.jgss requires java.logging jrt:/java.logging jdk.security.jgss requires java.security.sasl jrt:/java.security.sasl jdk.security.jgss requires java.security.jgss jrt:/java.security.jgss jdk.attach requires jdk.internal.jvmstat jrt:/jdk.internal.jvmstat jdk.jconsole requires jdk.attach jrt:/jdk.attach jdk.jconsole requires java.rmi jrt:/java.rmi jdk.jconsole requires jdk.management jrt:/jdk.management jdk.jconsole requires java.management jrt:/java.management jdk.jconsole requires jdk.management.agent jrt:/jdk.management.agent jdk.jconsole requires java.desktop jrt:/java.desktop jdk.jconsole requires jdk.internal.jvmstat jrt:/jdk.internal.jvmstat jdk.jconsole requires java.management.rmi jrt:/java.management.rmi jdk.accessibility requires java.desktop jrt:/java.desktop jdk.compiler requires java.compiler jrt:/java.compiler java.se requires java.datatransfer jrt:/java.datatransfer java.se requires java.compiler jrt:/java.compiler java.se requires java.scripting jrt:/java.scripting java.se requires java.desktop jrt:/java.desktop java.se requires java.security.sasl jrt:/java.security.sasl java.se requires java.naming jrt:/java.naming java.se requires java.sql.rowset jrt:/java.sql.rowset java.se requires java.security.jgss jrt:/java.security.jgss java.se requires java.sql jrt:/java.sql java.se requires java.management.rmi jrt:/java.management.rmi java.se requires java.management jrt:/java.management java.se requires java.xml.crypto jrt:/java.xml.crypto java.se requires java.instrument jrt:/java.instrument java.se requires java.rmi jrt:/java.rmi java.se requires java.prefs jrt:/java.prefs java.se requires java.logging jrt:/java.logging java.se requires java.xml jrt:/java.xml jdk.dynalink requires java.logging jrt:/java.logging jdk.security.auth requires java.naming jrt:/java.naming jdk.security.auth requires java.security.jgss jrt:/java.security.jgss jdk.management requires java.management jrt:/java.management jdk.scripting.nashorn requires java.logging jrt:/java.logging jdk.scripting.nashorn requires java.scripting jrt:/java.scripting jdk.scripting.nashorn requires jdk.dynalink jrt:/jdk.dynalink jdk.jsobject requires java.desktop jrt:/java.desktop jdk.xml.dom requires java.xml jrt:/java.xml jdk.jshell requires java.compiler jrt:/java.compiler jdk.jshell requires jdk.compiler jrt:/jdk.compiler jdk.jshell requires java.logging jrt:/java.logging jdk.jshell requires jdk.internal.opt jrt:/jdk.internal.opt jdk.jshell requires jdk.internal.le jrt:/jdk.internal.le jdk.jshell requires jdk.jdi jrt:/jdk.jdi jdk.jshell requires java.prefs jrt:/java.prefs jdk.jshell requires jdk.internal.ed jrt:/jdk.internal.ed jdk.jdi requires jdk.attach jrt:/jdk.attach jdk.jdi requires jdk.jdwp.agent jrt:/jdk.jdwp.agent jdk.javadoc requires java.xml jrt:/java.xml jdk.javadoc requires java.compiler jrt:/java.compiler jdk.javadoc requires jdk.compiler jrt:/jdk.compiler java.security.sasl requires java.logging jrt:/java.logging java.security.jgss requires java.naming jrt:/java.naming java.rmi requires java.logging jrt:/java.logging jdk.management.agent requires java.management jrt:/java.management jdk.management.agent requires java.management.rmi jrt:/java.management.rmi java.desktop requires java.xml jrt:/java.xml java.desktop requires java.prefs jrt:/java.prefs java.desktop requires java.datatransfer jrt:/java.datatransfer java.management.rmi requires java.naming jrt:/java.naming java.management.rmi requires java.management jrt:/java.management java.management.rmi requires java.rmi jrt:/java.rmi java.naming requires java.security.sasl jrt:/java.security.sasl java.sql.rowset requires java.logging jrt:/java.logging java.sql.rowset requires java.naming jrt:/java.naming java.sql.rowset requires java.sql jrt:/java.sql java.sql requires java.logging jrt:/java.logging java.sql requires java.xml jrt:/java.xml java.xml.crypto requires java.logging jrt:/java.logging java.xml.crypto requires java.xml jrt:/java.xml java.prefs requires java.xml jrt:/java.xml java.management binds java.management.rmi jrt:/java.management.rmi java.management binds jdk.management jrt:/jdk.management jdk.jshell binds jdk.editpad jrt:/jdk.editpad java.naming binds jdk.naming.dns jrt:/jdk.naming.dns java.naming binds jdk.naming.rmi jrt:/jdk.naming.rmi java.datatransfer binds java.desktop jrt:/java.desktop jdk.dynalink binds jdk.scripting.nashorn jrt:/jdk.scripting.nashorn java.base binds jdk.charsets jrt:/jdk.charsets java.base binds java.security.jgss jrt:/java.security.jgss java.base binds java.security.sasl jrt:/java.security.sasl java.base binds java.naming jrt:/java.naming java.base binds jdk.security.jgss jrt:/jdk.security.jgss java.base binds java.smartcardio jrt:/java.smartcardio java.base binds jdk.crypto.ec jrt:/jdk.crypto.ec java.base binds jdk.crypto.cryptoki jrt:/jdk.crypto.cryptoki java.base binds java.xml.crypto jrt:/java.xml.crypto java.base binds java.desktop jrt:/java.desktop java.base binds jdk.localedata jrt:/jdk.localedata java.base binds jdk.jlink jrt:/jdk.jlink java.base binds jdk.jdeps jrt:/jdk.jdeps java.base binds jdk.compiler jrt:/jdk.compiler java.base binds jdk.jartool jrt:/jdk.jartool java.base binds jdk.javadoc jrt:/jdk.javadoc java.base binds jdk.zipfs jrt:/jdk.zipfs java.base binds java.management jrt:/java.management java.base binds jdk.security.auth jrt:/jdk.security.auth java.base binds java.logging jrt:/java.logging java.compiler binds jdk.compiler jrt:/jdk.compiler java.compiler binds jdk.javadoc jrt:/jdk.javadoc jdk.internal.jvmstat binds jdk.jstatd jrt:/jdk.jstatd java.scripting binds jdk.scripting.nashorn jrt:/jdk.scripting.nashorn jdk.jstatd requires java.rmi jrt:/java.rmi jdk.jstatd requires jdk.internal.jvmstat jrt:/jdk.internal.jvmstat jdk.jdeps requires java.compiler jrt:/java.compiler jdk.jdeps requires jdk.compiler jrt:/jdk.compiler jdk.jlink requires jdk.jdeps jrt:/jdk.jdeps jdk.jlink requires jdk.internal.opt jrt:/jdk.internal.opt jdk.crypto.cryptoki requires jdk.crypto.ec jrt:/jdk.crypto.ec jdk.naming.rmi requires java.naming jrt:/java.naming jdk.naming.rmi requires java.rmi jrt:/java.rmi jdk.naming.dns requires java.naming jrt:/java.naming jdk.editpad requires java.desktop jrt:/java.desktop jdk.editpad requires jdk.internal.ed jrt:/jdk.internal.ed 

随着更多的挖掘,我在https://developer.jboss.org/thread/278334找到了解决方案,它指向了https://docs.jboss.org/author/display/WFLY10/Class+Loading+in+WildFly 。 本文有一个标题为“访问JDK类”的部分,其中指出默认情况下并非所有类都可用于部署,您需要将它们添加到jboss-deployment-structure.xml以使其可用。

就我而言:

            

该解决方案适用于

  • Wildfly 13,在Java 10.0.2上运行(9.0.4也可以)
  • 使用Java 8编译的应用程序
  • Mockito 1.10.19(我试过2.20.0但是有新的错误)

我认为问题可能是您使用的是早期版本的Java 9.在某些早期版本中,访问sun.reflect库时出现问题。 尝试将您的Java 9版本更新为版本9-ea+115之后的更高版本, 这是对类似(尽管不同)问题的答案中的建议。