–illegal-access
来替代–permit-illegal-access
选项。
–illegal-access=permit
–illegal-access=warn
–illegal-access=debug
–illegal-access=deny
–illegal-access
设置?➥ 如何设置这些选项?通过启动JVM时的参数吗?
➥ 在运行时如何获取当前值?
–illegal-access
来替代–permit-illegal-access
选项。
–illegal-access=permit
–illegal-access=warn
–illegal-access=debug
–illegal-access=deny
–illegal-access
设置?注意:在Java 16中,默认值为deny
(参见JEP 396:默认情况下强制封装JDK内部)。从Java 17开始,任何--illegal-access
参数都将被解释为deny
(参见JEP 403:强制封装JDK内部)。
是的,至少对于OpenJDK/OracleJDK来说,似乎确实发生了这种情况。该选项在java
工具的文档中列出。
执行java --help-extra
时也会列出该选项。
注意:JDK-11文档提到,这个选项将在未来的版本中被删除。
是的,这是一个命令行选项。例如:
java --illegal-access=deny --module-path <path> --module <module>/<main-class> [args...]
很遗憾,我不知道有什么方法可以在运行时查询该值。它似乎不是系统或环境属性的一部分。我尝试查找内部使用该值的位置,但未能找到(但说实话,我没有花太多时间寻找)。
为了方便起见,以下为JDK-11的--illegal-access
文档:
当出现在运行时,--illegal-access=
需要一个关键字parameter
来指定操作模式:
注意:
该选项将在未来版本中被删除。
permit
:此模式打开运行时映像中每个模块中的每个包,以对所有未命名模块(例如类路径上的代码)中的代码进行访问,如果该包存在于JDK 8中。这使得可以通过平台的各种反射API进行静态访问(例如,通过编译后的字节码)和深度反射访问。对任何此类包的第一个反射访问操作会发出警告。然而,在第一次出现后,不会发出任何警告。此单个警告描述了如何启用更多警告。这是当前JDK的默认模式,但在未来版本中将更改。
warn
:此模式与permit
相同,只是针对每个非法的反射访问操作会发出警告消息。
debug
:此模式与warn
相同,只是针对每个非法的反射访问操作会发出警告消息和堆栈跟踪。
deny
:此模式禁用除其他命令行选项启用的操作之外的所有非法访问操作,例如--add-opens
。此模式将在未来版本中成为默认值。
默认模式--illegal-access=permit
旨在使您意识到类路径上的代码至少一次反射访问任何JDK内部API。要了解所有这些访问,请使用warn
或debug
模式。对于需要非法访问的每个库或框架,您有两个选项:
如果组件维护者已经发布了一个不再使用JDK内部API的修复版本,则可以考虑升级到该版本。
如果该组件仍然需要进行修复,则可以联系其维护者,并要求他们使用适当的导出API替换其对JDK内部API的使用。
如果必须继续使用需要非法访问的组件,则可以使用一个或多个--add-opens
选项仅打开所需访问权限的内部包,以消除警告消息。
为了验证应用程序是否准备好使用JDK的未来版本,请使用--illegal-access=deny
以及任何必要的--add-opens
选项运行它。任何剩余的非法访问错误很可能是由已编译代码对JDK内部API的静态引用引起的。您可以通过使用带有--jdk-internals
选项的jdeps工具来识别这些问题。出于性能原因,当前的JDK不会针对非法的静态访问操作发出警告。
ManagementFactory.getRuntimeMXBean().getInputArguments()
,请参见https://dev59.com/ZXI_5IYBdhLWcg3wMf5_#1531999。 - Tomáš Záluský