Java 9 中有很多关于非法反射访问的问题。
我发现了很多关于解决错误消息的讨论,但我很想知道非法反射访问实际上是什么。
所以我的问题是:
什么定义了非法反射访问以及什么情况会触发警告?
我已经收集到它与 Java 9 中引入的封装原则有关,但我无法找到关于它们如何结合在一起、什么触发警告以及在什么情况下的解释。
除了了解模块及其各自包之间的访问之外。我相信它的症结在于 模块系统#Relaxed-strong- encapsulation ,我只会挑选它的相关部分来尝试回答这个问题。
为了帮助迁移到 Java-9,可以放松对模块的强封装。
实现可以提供 静态访问 ,即通过编译的字节码。
可以提供一种方法来调用其运行时系统,其中一个或多个模块的一个或多个包对 所有未命名模块 中的代码开放,即类路径上的代码。如果以这种方式调用运行时系统,并且如果这样做,反射 API 的某些调用会成功,否则它们会失败。
在这种情况下,您实际上最终进行了 “非法”的 反射访问 ,因为在纯模块化世界中,您不应该进行此类访问。 __
这一切是如何联系在一起的,在什么情况下会触发警告?
这种封装的放松在运行时由一个新的启动器选项控制--illegal-access,默认情况下在 Java9 中等于permit. 该permit模式确保
--illegal-access
permit
对任何此类包的第一次反射访问操作会导致发出警告,但在此之后不会发出警告。此单个警告描述了如何启用更多警告。无法抑制此警告。
这些模式可通过值debug(每次此类访问的消息和堆栈跟踪)、warn(每次此类访问的消息)和deny(禁用此类操作)进行配置。
debug
warn
deny
在应用程序上调试和修复的几件事是:-
--illegal-access=deny
opens``--add-opens
jdeps
--jdk-internals
检测到非法反射访问操作时发出的警告消息具有以下形式: WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM 在哪里: $PERPETRATOR是包含调用相关反射操作的代码以及代码源(即 JAR 文件路径)(如果可用)的类型的完全限定名称,并且 $VICTIM是描述正在访问的成员的字符串,包括封闭类型的完全限定名称
检测到非法反射访问操作时发出的警告消息具有以下形式:
WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM
在哪里:
$PERPETRATOR是包含调用相关反射操作的代码以及代码源(即 JAR 文件路径)(如果可用)的类型的完全限定名称,并且
$PERPETRATOR
$VICTIM是描述正在访问的成员的字符串,包括封闭类型的完全限定名称
$VICTIM
此类示例警告的问题: = JDK9:发生了非法反射访问操作。org.python.core.PySystemState
最后也是重要的一点,在尝试确保您不会面临此类警告并且未来安全时,您需要做的就是确保您的模块不会进行那些非法的反射访问。:)