Java“非法访问操作”方法将被弃用?
JDK 9+JVM发出非法访问操作警告后,如果您使用一些非法访问,如Java“非法访问操作”方法将被弃用?,java,java-11,java-reflection,Java,Java 11,Java Reflection,JDK 9+JVM发出非法访问操作警告后,如果您使用一些非法访问,如setAccessible() 我的问题 setAccessible()将来是否会被阻止 此功能的官方参考(如果不推荐)在哪里 我哪里都找不到参考资料,提前谢谢 WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.hazelcast.internal.networking.ni
setAccessible()
我的问题
setAccessible()
将来是否会被阻止WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.hazelcast.internal.networking.nio.SelectorOptimizer (file:/var/folders/9w/wp9vfqmn2ql0mp3lgym0bxf40000gn/T/toy.war-spring-boot-libs-0024b388-730f-430b-b21b-1611bd2ad612/hazelcast-4.0.2.jar) to field sun.nio.ch.SelectorImpl.selectedKeys
WARNING: Please consider reporting this to the maintainers of com.hazelcast.internal.networking.nio.SelectorOptimizer
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
1.setAccessible()
将来是否会被阻止?
不,就我所知,没有人反对它,也没有人计划反对它
您看到的警告与此方法有关,但不是直接的。Java 9中引入的Java平台模块系统在编译时和运行时(即反射)添加了更强的封装。运行时规则由#setAccessible(boolean)
记录:
类C
中的调用者可以使用此方法来启用对声明类D
的成员的访问,前提是以下任何一项保持不变:
和C
在同一模块中D
- 成员是公共的,
在包含D
的模块导出到至少包含D
的模块的包中是公共的C
- 成员受静态保护,
在包含D
的模块导出到至少包含D
的模块的包中是公共的,C
是C
的子类D
位于包含D
的模块至少打开到包含D
的模块的包中。未命名模块和打开模块中的所有包都对所有模块开放,因此当C
位于未命名模块或打开模块中时,此方法始终成功D
SecurityManager
)。突破性的更改是一个问题,因为Java以向后兼容性为荣。为了给库和框架提供足够的时间进行迁移,他们针对特定场景放松了这种强大的封装(见下文)
2.此功能的官方参考(将来将被弃用)在哪里? 您看到的警告与
--非法访问
选项有关,该选项由以下文件记录:
当在运行时出现时,--非法访问=
采用关键字参数来指定操作模式:
注意:此选项将在将来的版本中删除
:此模式打开运行时映像中每个模块中的每个包,以便在所有未命名模块(例如类路径上的代码)中编码(如果该包存在于JDK 8中)[强调添加]。这可以通过平台的各种反射API实现静态访问(例如,通过编译字节码和深度反射访问)。对任何此类包的第一次反射访问操作将导致发出警告。但是,首次发生后不会发出警告。此单一警告描述了如何启用更多警告此模式是当前JDK的默认模式,但在将来的版本中将更改[强调添加]permit
:此模式与“允许”模式相同,只是针对每个非法反射访问操作发出警告消息警告
:此模式与warn模式相同,只是针对每个非法反射访问操作都会发出警告消息和堆栈跟踪debug
:此模式禁用所有非法访问操作,但由其他命令行选项启用的操作除外,例如deny
此模式将成为未来版本的默认模式[强调添加]--add opens
--非法访问=许可
,旨在让您了解类路径上至少一次反射性访问任何JDK内部API的代码。要了解所有此类访问,可以使用警告或调试模式。对于类路径上需要非法访问的每个库或框架,您有两个选项:
-
如果组件的维护者已经发布了一个不再使用JDK内部API的固定版本,那么您可以考虑升级到那个版本。
- 如果组件仍然需要修复,那么您可以联系它的维护人员,让他们使用正确的导出API替换JDK内部API
--add opens
选项仅打开需要访问的内部软件包来消除警告消息
要验证您的应用程序是否已为JDK的未来版本做好准备,请使用--非法访问=拒绝
以及任何必要的--添加打开
选项运行它。任何剩余的非法访问错误都很可能是由于编译代码对JDK内部API的静态引用造成的。您可以通过运行带有--jdk internals
选项的jdeps
工具来识别它们。出于性能原因,当前的JDK不会对非法的静态访问操作发出警告
总结强调的部分:
permit
。
- 这允许未命名模块(即类路径)中的代码访问运行时映像(即JDK)中模块内的成员,即使这些成员位于未导出/未打开的包中(只要这些包