241 votes

qu'est-ce qu'un accès réflexif illégal

Il y a beaucoup de questions autour des propos illégaux réfléchissant accès à Java 9.

Maintenant, ce que je ne trouve pas parce que Google vomit est des gens qui essaient de contourner les messages d'erreur, est-ce illégal réfléchissant accès est réellement.

Donc ma question est assez simple:

Ce qui définit un illégales réfléchissant accès ainsi que les circonstances de déclenchement de l'avertissement?

J'ai compris que cela a quelque chose à voir avec l'encapsulation de principes qui ont été introduites dans Java 9, mais comment tout cela se tient et ce qui déclenche l'avertissement dans ce scénario, je ne peux pas trouver une explication.

90voto

nullpointer Points 1135

En dehors de la compréhension de l'accès entre les modules et les paquets. Je crois que le cœur du problème réside dans le Système de Module#Détendu-fort-encapsulation et je voudrais juste écrémer les parties pertinentes de la peine d'essayer et de répondre à la question.

Ce qui définit un illégales réfléchissant accès et quelles circonstances déclencher l'alerte?

Pour de l'aide dans la migration vers Java9, la forte encapsulation des modules pourraient être assouplies.

  • Une mise en œuvre peut fournir statique d'accès, c'est à dire par le code compilé.

  • Peut fournir un moyen d'invoquer son système d'exécution avec un ou plusieurs paquets d'un ou de plusieurs de ses modules ouverts à code dans tous les modules sans nom, c'est à dire à code sur le chemin de la classe. Si le système d'exécution est appelé de cette façon, et si, ce faisant, certaines invocations de la réflexion Api de réussir là où ils ont échoué.

Dans de tels cas, vous avez fini par faire un réfléchissant accès qui est "illégal" car, dans un pur monde modulaire vous n'étiez pas censé faire ces accès.

Comment tout cela se tient et ce qui déclenche l'alerte en ce qui scénario?

Cette relaxation de l'encapsulation est contrôlée à l'exécution, par un nouveau lanceur option --illegal-access qui, par défaut, dans Java9 est égal à permit. L' permit mode veille

La première réflexion opération d'accès à un tel paquet provoque une avertissement afin d'être émis, mais pas d'avertissements sont émis à partir de ce point. Ce simple avertissement décrit comment activer d'autres avertissements. Cette avertissement ne peut pas être supprimé.

Les modes sont configurables avec les valeurs de debug(message ainsi que stacktrace pour chaque accès), warn"(message pour chacun de ces accès) et deny(désactive ces opérations).


Peu de choses à déboguer et fixer sur les applications seraient les suivantes:-

  • L'exécuter en --illegal-access=deny pour apprendre à connaître et éviter d' ouvriring paquets à partir d'un module à l'autre sans un module de déclaration, y compris une directive(opens) ou une utilisation explicite de --add-opens VM arg.
  • Les références statiques de code compilé pour JDK-interne de l'Api peut être identifié à l'aide de l' jdeps outil --jdk-internals option

    Le message d'avertissement émis lorsqu'un illégales réfléchissant opération d'accès est détecté a la forme suivante:

    WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM
    

    où:

    $PERPETRATOR est le nom pleinement qualifié du type de contenant l' code qui a appelé la réflexion de l'opération en question et le code source (c'est à dire, JAR-chemin d'accès au fichier), si disponible, et

    $VICTIM est une chaîne qui décrit le membre en cours d'accès, y compris le nom pleinement qualifié de la enfermant type

Questions pour un échantillon d'avertissement: = JDK9: Un illégales réfléchissant accès opération a eu lieu. org.python.de base.PySystemState

Dernier et il est important de noter, tout en essayant de s'assurer que vous n'avez pas face à de telles mises en garde et sont avenir sûr, tout ce que vous devez faire est de vous assurer que vos modules ne sont pas ceux illégale réfléchissant accès. :)

27voto

ptomli Points 5778

Il y a un Oracle de l'article que j'ai trouvé concernant Java 9 module de système d'

Par défaut, un type dans un module n'est pas accessible à d'autres modules, sauf si c'est un type de public et de l'exportation de son emballage. Vous exposer uniquement les paquets que vous souhaitez exposer. Avec Java 9, cela s'applique également à la réflexion.

Comme l'a souligné dans https://stackoverflow.com/a/50251958/134894les différences entre l' AccessibleObject#setAccessible pour JDK8 et JDK9 sont instructifs. Plus précisément, JDK9 ajouté

Cette méthode peut être utilisée par l'appelant dans la classe C pour permettre l'accès à un membre de la classe de déclaration D si une des conditions suivantes se tiennent:

  • C et D sont dans le même module.
  • Le membre est public et D est public dans un paquet que le module contenant du D des exportations au moins le module contenant C.
  • Le membre est protégé statique, D est public dans un paquet que le module contenant du D des exportations au moins le module contenant C, et C est une sous-classe de D.
  • D est dans un package que le module contenant du D ouvre à au moins le module contenant C. Tous les paquets de nom et d'ouvrir des modules sont ouverts à tous les modules et donc cette méthode réussit toujours lorsque D est un sans nom ou d'ouvrir le module.

ce qui souligne l'importance de modules et de leurs exportations (en Java 9)

14voto

user158037 Points 2198

Il suffit de regarder setAccessible() méthode utilisée pour accéder private champs et 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 ya beaucoup plus les conditions requises pour que cette méthode fonctionne. La seule raison pour laquelle elle ne casse pas presque tous de l'ancien logiciel est que les modules générés automatiquement à partir de la plaine des Jarres sont très permissive (ouvert et l'exportation de tout pour tout le monde).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X