Есть много вопросов о незаконном отражающем доступе в Java 9.
Теперь то, что я не могу найти, потому что все, что Google изрыгает, - это люди, пытающиеся обойти сообщения об ошибках, это то, что на самом деле представляет собой незаконный доступ к отражению.
Итак, мой вопрос довольно прост:
Что определяет незаконный светоотражающий доступ и какие обстоятельства вызывают предупреждение?
Я понял, что это как-то связано с принципами инкапсуляции, которые были введены в Java 9, но с тем, как все это взаимосвязано и что вызывает предупреждение, в каком сценарии я не могу найти объяснения.
java
java-9
java-module
Tschallacka
источник
источник
Ответы:
Помимо понимания доступа между модулями и их соответствующими пакетами. Я считаю, что суть этого заключается в модульной системе # Relaxed-strong-encapsulation, и я бы просто выбрал соответствующие части, чтобы попытаться ответить на вопрос.
Чтобы облегчить переход на Java-9, можно ослабить строгую инкапсуляцию модулей.
Реализация может обеспечивать статический доступ , то есть с помощью скомпилированного байт-кода.
Может предоставлять средства для вызова своей исполняющей системы с одним или несколькими пакетами одного или нескольких ее модулей, открытых для кода во всех безымянных модулях , то есть для кода в пути к классам. Если система времени выполнения вызывается таким образом, и если при этом некоторые вызовы API-интерфейсов отражения завершаются успешно, в противном случае они потерпели бы неудачу.
В таких случаях вы фактически закончили тем, что сделали рефлексивный доступ, который является «незаконным», поскольку в чисто модульном мире вы не должны были делать такие доступы.
Это ослабление инкапсуляции контролируется во время выполнения с помощью новой опции запуска,
--illegal-access
которая по умолчанию в Java9 равнаpermit
. Вpermit
режиме гарантируетРежимы конфигурируются значениями
debug
(сообщение, а также трассировка стека для каждого такого доступа),warn
(сообщение для каждого такого доступа) иdeny
(отключает такие операции).Вот несколько вещей, которые нужно отлаживать и исправлять в приложениях:
--illegal-access=deny
чтобы узнать и избежать открытия пакетов от одного модуля к другому без объявления модуля, включая такую директиву (opens
) или явного использования--add-opens
аргумента VM arg.jdeps
инструмента с--jdk-internals
опциейВопросы для такого образца предупреждения: = JDK9: Произошла недопустимая операция отражающего доступа. org.python.core.PySystemState
Последнее и важное замечание: при попытке гарантировать, что вы не столкнетесь с такими предупреждениями и будете в безопасности в будущем, все, что вам нужно сделать, это убедиться, что ваши модули не делают эти незаконные отражающие доступы. :)
источник
Я нашел статью Oracle о модульной системе Java 9.
Как указано в https://stackoverflow.com/a/50251958/134894 , различия между
AccessibleObject#setAccessible
JDK8 и JDK9 поучительны. В частности, JDK9 добавилчто подчеркивает важность модулей и их экспорта (в Java 9)
источник
–illegal-access=permit
...fun
Просто посмотрите на
setAccessible()
метод, используемый для доступа кprivate
полям и методам:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-
https://docs.oracle.com/javase/9/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-
Теперь для работы этого метода требуется гораздо больше условий. Единственная причина, по которой он не ломает почти все старое программное обеспечение, заключается в том, что модули, автоматически созданные из простых JAR-файлов, очень разрешительны (открывать и экспортировать все для всех).
источник
Если вы хотите использовать опцию add-open, вот команда, чтобы узнать, какой модуль предоставляет какой пакет ->
java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d
имя модуля будет показано с @, а имя пакетов без него
ПРИМЕЧАНИЕ: протестировано с JDK 11
ВАЖНО: очевидно, что лучше, чем провайдер пакета не делает незаконный доступ
источник