Il y a beaucoup de questions autour de l'accès réflexif illégal dans Java 9.
Maintenant, ce que je ne peux pas trouver, car tout ce que Google crache, ce sont des gens qui essaient de contourner les messages d'erreur, c'est ce qu'est en réalité un accès réflexif illégal.
Ma question est donc assez simple:
Qu'est-ce qui définit un accès réflexif illégal et quelles circonstances déclenchent l'avertissement?
J'ai compris que cela a quelque chose à voir avec les principes d'encapsulation qui ont été introduits dans Java 9, mais comment tout cela se tient ensemble et ce qui déclenche l'avertissement dans quel scénario je ne trouve pas d'explication.
java
java-9
java-module
Tschallacka
la source
la source
Réponses:
Outre une compréhension des accès entre les modules et leurs packages respectifs. Je crois que l'essentiel réside dans le système de module # Encapsulation forte-détendue et je choisirais simplement les parties pertinentes pour essayer de répondre à la question.
Pour faciliter la migration vers Java-9, l'encapsulation forte des modules pourrait être assouplie.
Une implémentation peut fournir un accès statique , c'est-à-dire par bytecode compilé.
Peut fournir un moyen d'invoquer son système d'exécution avec un ou plusieurs packages d'un ou plusieurs de ses modules ouverts au code dans tous les modules sans nom , c'est-à-dire au code sur le chemin de classe. Si le système d'exécution est appelé de cette manière, et si, ce faisant, certaines invocations des API de réflexion réussissent, sinon elles auraient échoué.
Dans de tels cas, vous avez fini par créer un accès réfléchi qui est "illégal" puisque dans un monde purement modulaire, vous n'étiez pas censé faire de tels accès.
Cette relaxation de l'encapsulation est contrôlée à l'exécution par une nouvelle option de lanceur
--illegal-access
qui par défaut en Java9 est égalepermit
. Lepermit
mode assureLes modes sont configurables avec des valeurs
debug
(message ainsi que stacktrace pour chacun de ces accès),warn
(message pour chacun de ces accès) etdeny
(désactive ces opérations).Peu de choses à déboguer et à corriger sur les applications seraient: -
--illegal-access=deny
pour connaître et éviter d' ouvrir des packages d'un module à un autre sans déclaration de module incluant une telle directive (opens
) ou utilisation explicite de--add-opens
VM arg.jdeps
outil avec l'--jdk-internals
optionQuestions pour un tel exemple d'avertissement: = JDK9: une opération d'accès réfléchissant illégale s'est produite. org.python.core.PySystemState
Enfin et une note importante, tout en essayant de vous assurer que vous ne faites pas face à de tels avertissements et que vous êtes en sécurité pour l'avenir, tout ce que vous avez à faire est de vous assurer que vos modules n'effectuent pas ces accès réfléchissants illégaux. :)
la source
J'ai trouvé un article Oracle concernant le système de modules Java 9
Comme indiqué dans https://stackoverflow.com/a/50251958/134894 , les différences entre le
AccessibleObject#setAccessible
pour JDK8 et JDK9 sont instructives. Plus précisément, JDK9 a ajoutéqui met en évidence l'importance des modules et de leurs exportations (en Java 9)
la source
–illegal-access=permit
...fun
Regardez simplement la
setAccessible()
méthode utilisée pour accéder auxprivate
champs et aux méthodes: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-
Maintenant, il y a beaucoup plus de conditions requises pour que cette méthode fonctionne. La seule raison pour laquelle il ne casse pas presque tous les anciens logiciels est que les modules générés automatiquement à partir de JAR simples sont très permissifs (tout ouvrir et exporter pour tout le monde).
la source
Si vous souhaitez utiliser l'option add-open, voici une commande pour trouver quel module fournit quel package ->
java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d
le nom du module sera affiché avec le @ tandis que le nom des packages sans lui
REMARQUE: testé avec JDK 11
IMPORTANT: c'est évidemment mieux que le fournisseur du package ne fasse pas l'accès illégal
la source