什么是非法反射访问? [英] What is an illegal reflective access?

查看:41
本文介绍了什么是非法反射访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

所以我的问题是:

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

据我所知,它与 Java 9 中引入的封装原则有关,但我找不到关于它们如何结合在一起、触发警告的原因以及在什么情况下的解释.

解决方案

除了了解模块及其各自包之间的访问之外.我相信它的症结在于 Module System#Relaxed-strong-封装,我会挑选其中的相关部分来尝试回答问题.

<块引用>

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

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

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

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

在这种情况下,您实际上最终进行了反射访问,这是非法",因为在纯粹的模块化世界中,您并不打算这样做访问.

<块引用>

这一切是如何联系在一起的,以及触发警告的原因是什么场景?

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

<块引用>

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

模式可配置值debug(消息以及每次此类访问的堆栈跟踪)、warn(每次此类访问的消息)和deny(禁用此类操作).


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

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

非法反射访问操作时发出的警告信息检测到的形式如下:

警告:$PERPETRATOR 对 $VICTIM 的非法反射访问

<块引用>

哪里:

$PERPETRATOR 是包含调用相关反射操作的代码加上代码源(即 JAR 文件路径)(如果可用)和

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

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

最后一个重要的注意事项,在努力确保您不会面临此类警告并且未来安全的同时,您需要做的就是确保您的模块不会进行那些非法的反射访问.:)

There are a lot of questions about illegal reflective access in Java 9.

I have found plenty of discussion about working around the error messages, but I would love to know what an illegal reflective access actually is.

So my question is:

What defines an illegal reflective access and what circumstances trigger the warning?

I have gathered that it has something to do with the encapsulation principles that were introduced in Java 9, but I can't find an explanation of how it all hangs together, what triggers the warning, and in what scenario.

解决方案

Apart from an understanding of the accesses amongst modules and their respective packages. I believe the crux of it lies in the Module System#Relaxed-strong-encapsulation and I would just cherry-pick the relevant parts of it to try and answer the question.

What defines an illegal reflective access and what circumstances trigger the warning?

To aid in the migration to Java-9, the strong encapsulation of the modules could be relaxed.

  • An implementation may provide static access, i.e. by compiled bytecode.

  • May provide a means to invoke its run-time system with one or more packages of one or more of its modules open to code in all unnamed modules, i.e. to code on the classpath. If the run-time system is invoked in this way, and if by doing so some invocations of the reflection APIs succeed where otherwise they would have failed.

In such cases, you've actually ended up making a reflective access which is "illegal" since in a pure modular world you were not meant to do such accesses.

How it all hangs together and what triggers the warning in what scenario?

This relaxation of the encapsulation is controlled at runtime by a new launcher option --illegal-access which by default in Java9 equals permit. The permit mode ensures

The first reflective-access operation to any such package causes a warning to be issued, but no warnings are issued after that point. This single warning describes how to enable further warnings. This warning cannot be suppressed.

The modes are configurable with values debug(message as well as stacktrace for every such access), warn(message for each such access), and deny(disables such operations).


Few things to debug and fix on applications would be:-

  • Run it with --illegal-access=deny to get to know about and avoid opening packages from one module to another without a module declaration including such a directive(opens) or explicit use of --add-opens VM arg.
  • Static references from compiled code to JDK-internal APIs could be identified using the jdeps tool with the --jdk-internals option

The warning message issued when an illegal reflective-access operation is detected has the following form:

WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM

where:

$PERPETRATOR is the fully-qualified name of the type containing the code that invoked the reflective operation in question plus the code source (i.e., JAR-file path), if available, and

$VICTIM is a string that describes the member being accessed, including the fully-qualified name of the enclosing type

Questions for such a sample warning: = JDK9: An illegal reflective access operation has occurred. org.python.core.PySystemState

Last and an important note, while trying to ensure that you do not face such warnings and are future safe, all you need to do is ensure your modules are not making those illegal reflective accesses. :)

这篇关于什么是非法反射访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆