Почему в Groovy отображается предупреждение "Произошла недопустимая операция доступа с отражением" при использовании JDK11
Когда я использую 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:
горячая точка / время выполнения ➜ JEP 181 Управление доступом на основе гнезд
Представьте гнезда, контекст управления доступом, который соответствует существующему представлению о вложенных типах в языке программирования Java (JEP-181: Управление доступом на основе гнезд).
В Java SE 11 виртуальная машина Java поддерживает размещение классов и интерфейсов в новый контекст управления доступом, называемый гнездом. Гнезда позволяют классам и интерфейсам, которые логически являются частью одного и того же объекта кода, но скомпилированы в отдельные файлы классов, для доступа к закрытым членам друг друга без необходимости в компиляторах вставлять методы моста, расширяющие доступность. Гнезда являются низкоуровневым механизмом платформы Java SE; нет никаких изменений в правилах контроля доступа языка программирования Java. Компилятор javac был обновлен, чтобы использовать гнезда при компиляции вложенных классов и интерфейсов в исходном коде Java, создав новые атрибуты файлов классов, которые помещают класс (или интерфейс) верхнего уровня и все его вложенные классы и интерфейсы в одно и то же гнездо. Виртуальная машина Java была обновлена для использования этих атрибутов при проверке доступности частного конструктора, метода или поля, в том числе с помощью отражения ядра и API java.lang.invoke.MethodHandles.Lookup. Членство в гнезде предоставляется с помощью новых методов getNestHost и getNestMembers из java.lang.Class.
Поскольку членство в гнезде записывается в файле класса класса или интерфейса верхнего уровня (хоста гнезда), этот файл класса должен присутствовать во время выполнения, чтобы можно было выполнять проверки контроля доступа. Обычно это не проблема, поскольку класс или интерфейс верхнего уровня обычно используются напрямую. В некотором коде, где класс или интерфейс верхнего уровня действует только как держатель для вложенных классов или интерфейсов и в остальном не используется, инструменты упаковки могли исключить этот файл класса из дистрибутива библиотеки или приложения. При управлении доступом на основе гнезд больше невозможно исключить класс или интерфейс верхнего уровня, если какой-либо из вложенных классов или интерфейсов требует доступа к закрытым членам друг друга - будет выброшено исключение NoClassDefFoundError или ClassNotFoundException. Источник
Таким образом, java изменил правила того, как устанавливается контроль доступа во время выполнения, и в результате Groovy, который, кажется, является языком, который использует платформу java и ее библиотеки, не может использовать отражение для доступа к закрытым членам.
Oracle ожидала такого рода проблемы с этим изменением и поместила сообщение об ошибке с просьбой сообщить о проблеме создателям нарушающего плагина.