Hay muchas preguntas sobre el acceso reflectante ilegal en Java 9.
Ahora, lo que no puedo encontrar porque todo lo que Google arroja son personas que intentan evitar los mensajes de error, es lo que realmente es un acceso reflectante ilegal.
Entonces mi pregunta bastante simple es:
¿Qué define un acceso reflectante ilegal y qué circunstancias desencadenan la advertencia?
He deducido que tiene algo que ver con los principios de encapsulación que se introdujeron en Java 9, pero cómo todo encaja y qué desencadena la advertencia en qué escenario no puedo encontrar una explicación.
java
java-9
java-module
Tschallacka
fuente
fuente
Respuestas:
Además de una comprensión de los accesos entre módulos y sus respectivos paquetes. Creo que el quid de esto radica en el Sistema de módulos # Relajado-fuerte-encapsulado y simplemente seleccionaría las partes relevantes para tratar de responder la pregunta.
Para ayudar en la migración a Java-9, se podría relajar la encapsulación sólida de los módulos.
Una implementación puede proporcionar acceso estático , es decir, mediante código de bytes compilado.
Puede proporcionar un medio para invocar su sistema de tiempo de ejecución con uno o más paquetes de uno o más de sus módulos abiertos para codificar en todos los módulos sin nombre , es decir, para codificar en el classpath. Si el sistema de tiempo de ejecución se invoca de esta manera, y si al hacerlo, algunas invocaciones de las API de reflexión tienen éxito donde de otro modo habrían fallado.
En tales casos, en realidad ha terminado haciendo un acceso reflectante que es "ilegal" ya que en un mundo modular puro no estaba destinado a hacer tales accesos.
Esta relajación de la encapsulación se controla en tiempo de ejecución mediante una nueva opción
--illegal-access
de iniciador que, por defecto, en Java9 es igualpermit
. Elpermit
modo aseguraLos modos se pueden configurar con valores
debug
(mensaje y seguimiento de pila para cada acceso),warn
(mensaje para cada acceso) ydeny
(deshabilita tales operaciones).Algunas cosas para depurar y corregir en aplicaciones serían: -
--illegal-access=deny
para conocer y evitar abrir paquetes de un módulo a otro sin una declaración de módulo que incluya dicha directiva (opens
) o el uso explícito de--add-opens
VM arg.jdeps
herramienta con la--jdk-internals
opciónPreguntas para este ejemplo de advertencia: = JDK9: Se ha producido una operación de acceso reflectante ilegal. org.python.core.PySystemState
Por último, y una nota importante, mientras trata de asegurarse de que no se enfrenta a tales advertencias y está a salvo en el futuro, todo lo que necesita hacer es asegurarse de que sus módulos no hagan esos accesos reflectantes ilegales. :)
fuente
Hay un artículo de Oracle que encontré sobre el sistema de módulos Java 9
Como se señala en https://stackoverflow.com/a/50251958/134894 , las diferencias entre
AccessibleObject#setAccessible
JDK8 y JDK9 son instructivas. Específicamente, JDK9 agregóque destaca la importancia de los módulos y sus exportaciones (en Java 9)
fuente
–illegal-access=permit
...fun
Solo mire el
setAccessible()
método utilizado para acceder a losprivate
campos y métodos: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-
Ahora se requieren muchas más condiciones para que este método funcione. La única razón por la que no rompe casi todo el software anterior es que los módulos generados automáticamente a partir de JAR simples son muy permisivos (abren y exportan todo para todos).
fuente
Si desea optar por la opción agregar-abrir, aquí hay un comando para encontrar qué módulo proporciona qué paquete ->
java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d
el nombre del módulo se mostrará con @ mientras que el nombre de los paquetes sin él
NOTA: probado con JDK 11
IMPORTANTE: obviamente es mejor que el proveedor del paquete no haga el acceso ilegal
fuente