当前位置: 首页 > 面试题库 >

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

鲁展
2023-03-14
问题内容

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

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.<init>(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以使其可用。

就我而言:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
    <deployment>
        <dependencies>
            <system export="true">
                <paths>
                    <path name="sun/reflect"/>
                </paths>
            </system>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

该解决方案适用于

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


 类似资料:
  • 食氧;视窗7;JDK 9决赛从9日开始,21日结束;JUnit4.12和现有的应用程序。作为起点,可以编译、执行应用程序,并且所有JUnit测试都显示为绿色。现在我们使用eclipse生成文件模块信息。JAVA结果是: 但有一个错误:junit无法解析为模块。问题是:如何告诉文件junit没有定义任何模块,应该在兼容模式下运行?

  • 问题内容: 我直到今天才开始了解Mockito。我写了一些简单的测试(使用JUnit,请参见下文),但是我不知道如何在Spring的托管bean中使用模拟对象。什么是使用Spring的最佳实践。我应该如何向我的bean注入模拟依赖项? 你可以跳过这一步,直到回到我的问题。 首先,我学到了什么。这是一篇很好的文章Mocks Are n’t Stubs,它解释了基础知识(Mock的检查行为验证而不是状

  • 我试图理解在Mockito的情况下泛型是如何工作的。 我试图模拟,但是下面的代码不能编译,我不知道为什么: 为什么会这样? 和有什么区别? 他们应该是一样的,对吧?

  • 你可以跳过这个直到回到我的问题。 首先,我学到了什么。这是一篇很好的文章,它解释了基础(mock的检查、行为验证,而不是状态验证)。然后有一个很好的例子,这里是Mockito,这里是Mockito更容易的嘲弄。我们解释了mockito的mock对象既是mock又是stub。 在这里Mockito和这里Matchers,你可以找到更多的例子。 我不太明白最后两个环节...有人能给我解释一下Sprin

  • Java文档可以使用工具生成。 它目前以格式生成文档。 在java 9中,可以通过在命令行参数中使用选项生成格式的文档。 旧式的java文档 考虑F:\worksp\java9文件夹中有一个Java文件:Tester.java,其代码如下 - 可以运行jdk 7 的javadoc工具来生成文档。 使用标志运行jdk 9的javadoc工具以生成新类型的文档。 打开生成的文件,如下所示 -

  • 我在SearchString.contains(“”),我正在尝试调用“when(...).thenreturn(...)”但是mockito抛出了一个异常,说“不能mock/spy class java.lang.String”我不确定在测试这个web服务时我做得是否正确。也许有别的方法可以做到这一点?下面是我的测试类: