小编典典

什么是非法反射访问?

all

Java 9 中有很多关于非法反射访问的问题。

我发现了很多关于解决错误消息的讨论,但我很想知道非法反射访问实际上是什么。

所以我的问题是:

什么定义了非法反射访问以及什么情况会触发警告?

我已经收集到它与 Java 9 中引入的封装原则有关,但我无法找到关于它们如何结合在一起、什么触发警告以及在什么情况下的解释。


阅读 67

收藏
2022-06-22

共1个答案

小编典典

除了了解模块及其各自包之间的访问之外。我相信它的症结在于 模块系统#Relaxed-strong-
encapsulation
,我只会挑选它的相关部分来尝试回答这个问题。

什么定义了非法反射访问以及什么情况会触发警告?

为了帮助迁移到 Java-9,可以放松对模块的强封装。

  • 实现可以提供 静态访问 ,即通过编译的字节码。

  • 可以提供一种方法来调用其运行时系统,其中一个或多个模块的一个或多个包对 所有未命名模块 中的代码开放,即类路径上的代码。如果以这种方式调用运行时系统,并且如果这样做,反射 API 的某些调用会成功,否则它们会失败。

在这种情况下,您实际上最终进行了 “非法”的 反射访问 ,因为在纯模块化世界中,您不应该进行此类访问。 __

这一切是如何联系在一起的,在什么情况下会触发警告?

这种封装的放松在运行时由一个新的启动器选项控制--illegal-access,默认情况下在 Java9 中等于permit.
permit模式确保

对任何此类包的第一次反射访问操作会导致发出警告,但在此之后不会发出警告。此单个警告描述了如何启用更多警告。无法抑制此警告。

这些模式可通过值debug(每次此类访问的消息和堆栈跟踪)、warn(每次此类访问的消息)和deny(禁用此类操作)进行配置。


在应用程序上调试和修复的几件事是:-

  • 运行它--illegal-access=deny以了解并避免在没有包含此类指令( )或显式使用VM arg的模块声明的情况下从一个模块 打开包到另一个模块。opens``--add-opens
  • 可以使用带有选项的jdeps工具识别从编译代码到 JDK 内部 API 的静态引用--jdk-internals

检测到非法反射访问操作时发出的警告消息具有以下形式:

WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM

在哪里:

$PERPETRATOR是包含调用相关反射操作的代码以及代码源(即 JAR 文件路径)(如果可用)的类型的完全限定名称,并且

$VICTIM是描述正在访问的成员的字符串,包括封闭类型的完全限定名称

此类示例警告的问题: =
JDK9:发生了非法反射访问操作。org.python.core.PySystemState

最后也是重要的一点,在尝试确保您不会面临此类警告并且未来安全时,您需要做的就是确保您的模块不会进行那些非法的反射访问。:)

2022-06-22