Abgesehen von einem Verständnis der Zugriffe zwischen Modulen und ihren jeweiligen Paketen. Ich glaube, der Kern davon liegt im Modulsystem # Relaxed-strong-encapsulation, und ich würde nur die relevanten Teile davon auswählen, um zu versuchen, die Frage zu beantworten.
Was definiert einen illegalen reflektierenden Zugang und welche Umstände lösen die Warnung aus?
Um die Migration auf Java-9 zu unterstützen, könnte die starke Kapselung der Module gelockert werden.
Eine Implementierung kann statischen Zugriff bereitstellen , dh durch kompilierten Bytecode.
Kann eine Möglichkeit bieten, sein Laufzeitsystem mit einem oder mehreren Paketen eines oder mehrerer seiner Module aufzurufen, die für den Code in allen unbenannten Modulen geöffnet sind , dh für den Code im Klassenpfad. Wenn das Laufzeitsystem auf diese Weise aufgerufen wird und wenn dadurch einige Aufrufe der Reflection-APIs erfolgreich sind, wo sie sonst fehlgeschlagen wären.
In solchen Fällen haben Sie tatsächlich einen reflektierenden Zugriff vorgenommen, der "illegal" ist, da Sie in einer rein modularen Welt solche Zugriffe nicht durchführen sollten.
Wie hängt alles zusammen und was löst in welchem Szenario die Warnung aus?
Diese Lockerung der Kapselung wird zur Laufzeit durch eine neue Launcher-Option gesteuert, --illegal-access
die in Java9 standardmäßig gleich ist permit
. Der permit
Modus sorgt dafür
Die erste Operation mit reflektierendem Zugriff auf ein solches Paket bewirkt, dass eine Warnung ausgegeben wird, aber nach diesem Punkt werden keine Warnungen ausgegeben. Diese einzelne Warnung beschreibt, wie Sie weitere Warnungen aktivieren. Diese Warnung kann nicht unterdrückt werden.
Die Modi können mit Werten debug
(Nachricht sowie Stapelverfolgung für jeden solchen Zugriff), warn
(Nachricht für jeden solchen Zugriff) und deny
(deaktiviert solche Operationen) konfiguriert werden .
Einige Dinge, die zum Debuggen und Beheben von Anwendungen erforderlich sind, sind:
- Führen Sie es mit aus
--illegal-access=deny
, um zu erfahren, wie Sie Pakete von einem Modul zum anderen öffnen können , ohne eine Moduldeklaration mit einer solchen Direktive ( opens
) oder einer expliziten Verwendung von--add-opens
VM arg.
- Statische Verweise von kompiliertem Code auf JDK-interne APIs konnten mithilfe des
jdeps
Tools mit der --jdk-internals
Option identifiziert werden
Die Warnmeldung, die ausgegeben wird, wenn eine illegale Operation mit reflektierendem Zugriff erkannt wird, hat die folgende Form:
WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM
wo:
$PERPETRATOR
ist der vollständig qualifizierte Name des Typs, der den Code enthält, der die betreffende Reflexionsoperation aufgerufen hat, sowie die Codequelle (dh JAR-Dateipfad), falls verfügbar, und
$VICTIM
ist eine Zeichenfolge, die das Mitglied beschreibt, auf das zugegriffen wird, einschließlich des vollständig qualifizierten Namens des umschließenden Typs
Fragen zu einer solchen Beispielwarnung: = JDK9: Es ist eine unzulässige reflektierende Zugriffsoperation aufgetreten. org.python.core.PySystemState
Der letzte und wichtige Hinweis: Während Sie sicherstellen möchten, dass Sie nicht vor solchen Warnungen stehen und zukunftssicher sind, müssen Sie lediglich sicherstellen, dass Ihre Module keine illegalen reflektierenden Zugriffe ausführen. :) :)