获取 Java 中 `-illegal-access` 设置的当前值

Posted

技术标签:

【中文标题】获取 Java 中 `-illegal-access` 设置的当前值【英文标题】:Get the current value of `-illegal-access` setting in Java 【发布时间】:2019-05-16 08:12:16 【问题描述】:

这篇文章 JDK 9: Proposal to allow illegal reflective access by default 声称 –permit-illegal-access 选项将被更通用的选项 –illegal-access 取代。

–illegal-access=permit –illegal-access=warn –illegal-access=debug –illegal-access=deny

➥ 发生了吗?有–illegal-access 设置吗?

➥ 这些是如何设置的?启动 JVM 的参数?

➥ 如何在运行时获取当前值?

【问题讨论】:

为什么在运行时需要这个值? 注意: 从 Java 16 开始,--illegal-access 值现在默认为 deny(请参阅 JEP 396: Strongly Encapsulate JDK Internals by Default),--illegal-access 选项本身设置为在 Java 17 中无效(即所有值都等同于 deny;参见 JEP 403: Strongly Encapsulate JDK Internals)。 【参考方案1】:

那发生了吗?是否有--illegal-access设置?

是的,似乎确实发生了——至少对于 OpenJDK/OracleJDK 而言。该选项列在java“工具”的文档中。

JDK-9 documentation JDK-10 documentation JDK-11 documentation

执行java --help-extra时也会列出来。

注意:JDK-11 文档提到此选项将在未来的版本中删除。


这些是如何设置的?启动 JVM 的参数?

是的,它是一个命令行选项。示例:

java --illegal-access=deny --module-path <path> --module <module>/<main-class> [args...]

如何在运行时获取当前值?

不幸的是,我不知道有什么方法可以在运行时查询该值。它似乎不是系统或环境属性的一部分。我尝试找到该值在内部使用的位置,但无法找到(但老实说,我并没有花太多时间寻找)。


为方便起见,这里是 JDK-11 的 --illegal-access 的文档:

--illegal-access=参数

在运行时出现时,--illegal-access= 采用关键字 parameter 来指定操作模式:

注意:

此选项将在未来的版本中移除。

permit:此模式打开运行时映像中每个模块中的每个包以编码所有未命名模块(例如类路径上的代码),如果该包存在于 JDK 8 中。这启用通过平台的各种反射 API 进行静态访问(例如,通过编译的字节码和深度反射访问)。对任何此类包的第一次反射访问操作会导致发出警告。但是,第一次发生后不会发出警告。此单个警告描述了如何启用更多警告。此模式是当前 JDK 的默认模式,但会在未来版本中更改。

warn:此模式与permit 相同,只是对于每个非法反射访问操作都会发出警告消息。

debug:此模式与warn 相同,只是对于每个非法反射访问操作都会发出警告消息和堆栈跟踪。

deny:此模式禁用所有非法访问操作,但由其他命令行选项启用的操作除外,例如--add-opens。此模式将在未来版本中成为默认模式。

默认模式--illegal-access=permit 旨在让您了解类路径上的代码至少一次反射性地访问任何 JDK 内部 API。要了解所有此类访问,您可以使用warndebug 模式。对于需要非法访问的类路径上的每个库或框架,您有两种选择:

如果组件的维护者已经发布了一个不再使用 JDK 内部 API 的固定版本,那么您可以考虑升级到该版本。

如果组件仍然需要修复,那么您可以联系其维护人员并要求他们将使用的 JDK 内部 API 替换为正确的导出 API。

如果您必须继续使用需要非法访问的组件,则可以通过使用一个或多个 --add-opens 选项来消除警告消息,以仅打开需要访问的内部包。

要验证您的应用程序是否已为 JDK 的未来版本做好准备,请使用 --illegal-access=deny 以及任何必要的 --add-opens 选项运行它。任何剩余的非法访问错误很可能是由于从已编译代码到 JDK 内部 API 的静态引用。您可以通过运行带有--jdk-internals 选项的jdeps 工具来识别它们。出于性能原因,当前的 JDK 不会针对非法静态访问操作发出警告。

【讨论】:

以上是关于获取 Java 中 `-illegal-access` 设置的当前值的主要内容,如果未能解决你的问题,请参考以下文章

java中获取本地IP地址

java中如何获取结果集ResutSet的总条数?

在java中怎么获取页面的路径

java 通过反射怎么获取方法中参数值

java中如何获取目录中的所有文件

java中,如何获取真实的IP地址?