为什么当我使用 JDK11 时,groovy 显示警告“发生了非法反射访问操作”

为什么当我使用 JDK11 时,groovy 显示警告“发生了非法反射访问操作”

当我使用 JDK11,然后安装 Groovy 时,出现了一些如下警告:

WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v7.Java7$1 (file:/D:/Groovy/groovy-2.5.7/lib/groovy-2.5.7.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int) WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v7.Java7$1 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 Groovy Version: 2.5.7 JVM: 11.0.3 Vendor: Oracle Corporation OS: Windows 10

当我使用 JDK 8 时,没有任何警告,有人知道原因吗?

答案1

请参阅 JDK11 发行说明中的​​这段引文:

hotspot/runtime ➜ JEP 181 基于嵌套的访问控制

引入嵌套,这是一种访问控制上下文,与 Java 编程语言中现有的嵌套类型概念一致(JEP-181:基于嵌套的访问控制)。

在 Java SE 11 中,Java 虚拟机支持将类和接口安排到新的访问控制上下文(称为嵌套)中。嵌套允许逻辑上属于同一代码实体但被编译为不同类文件的类和接口访问彼此的私有成员,而无需编译器插入可访问性扩展桥接方法。嵌套是 Java SE 平台的低级机制;Java 编程语言的访问控制规则没有任何变化。javac 编译器已更新,可在 Java 源代码中编译嵌套类和接口时使用嵌套,方法是生成新的类文件属性,将顶级类(或接口)及其所有嵌套类和接口放在同一个嵌套中。Java 虚拟机已更新,可在检查私有构造函数、方法或字段的可访问性时使用这些属性,包括通过核心反射和 java.lang.invoke.MethodHandles.Lookup API。嵌套中的成员身份通过 java.lang.Class 的新 getNestHost 和 getNestMembers 方法公开。

由于嵌套成员身份记录在顶级类或接口(嵌套主机)的类文件中,因此该类文件必须在运行时存在,以便执行访问控制检查。这通常不是问题,因为顶级类或接口通常直接使用。在某些代码中,顶级类或接口仅充当嵌套类或接口的容器,并且未使用,打包工具可能已从库或应用程序的分发中删除该类文件。使用基于嵌套的访问控制,如果任何嵌套类或接口需要访问彼此的私有成员,则不再可能删除顶级类或接口 - 将引发 NoClassDefFoundError 或 ClassNotFoundException。 来源

因此,java 改变了运行时建立访问控制的规则,结果,Groovy(这种看似利用 java 平台及其库的语言)无法使用反射来访问私有成员。

Oracle 预计这种更改会出现此类问题,并发出一条错误消息,要求您将该问题报告给有问题的插件的制造商。

相关内容