Automatische Module werden oft im Stackoverflow erwähnt, aber ich konnte keine vollständige, prägnante und autarke Definition eines automatischen Moduls finden.
Also, was ist ein automatisches Modul? Exportiert es alle Pakete? Öffnet es alle Pakete? Liest es alle anderen Module?
Ich beantworte zuerst deine eigentliche Frage ("Was ist ein automatisches Modul?"), aber ich erkläre auch, was sie dort sind für . Es ist schwer zu verstehen, warum sich automatische Module so verhalten, wie sie es ohne diese Informationen tun.
Das Modulsystem erstellt ein Modul aus jeder JAR, die es auf dem Modulpfad findet. Für modulare JARs (dh solche mit Moduldeskriptoren) ist dies einfach, da sie die Eigenschaften des Moduls (name , erfordert, Exporte) . Für einfache JARs (kein Moduldeskriptor) funktioniert dieser Ansatz nicht, was sollte das Modulsystem stattdessen tun? Es erstellt automatisch ein Modul - ein automatisches Modul sozusagen - und nimmt die sichersten Vermutungen für die drei Eigenschaften.
Das Ableiten des Namens erfolgt in zwei Schritten:
Automatic-Module-Name
in ihrem Manifest definiert, definiert sie den Modulnamen Der zweite Ansatz ist von Natur aus instabil, daher sollten keine Module veröffentlicht werden, die von einem solchen automatischen Modul abhängig sind. Maven warnt davor.
Da eine einfache JAR-Klausel keine Klausel requires ausdrückt, lässt das Modulsystem alle anderen Module, die es in die Lesbarkeitsdiagramm (aka Moduldiagramm). Im Gegensatz zu expliziten Modulen lesen automatische auch das unbenannte Modul, das alles enthält, was aus dem Klassenpfad geladen wurde. Dieses scheinbar kleine Detail erweist sich als sehr wichtig (siehe unten).
Automatische Module haben jedoch noch weitere Lesbarkeits-Macken:
Zusammengenommen kann dies den unglücklichen Effekt haben, dass ein explizites Modul (dh ein nicht-automatisiertes), das von mehreren einfachen JARs abhängt, nur eines benötigt (solange die anderen auf dem Modulpfad landen) so gut).
Da die JAR keine Informationen enthält, welche Pakete als öffentliche APIs betrachtet werden und welche nicht, exportiert das Modulsystem alle Pakete und öffnet sie auch für die Tiefenreflexion.
Das Modulsystem scannt auch META-INF/services
und veranlasst das automatische Modul, die darin genannten Dienste bereitzustellen. Ein automatisches Modul darf alle Dienste nutzen.
Schließlich wird auch der Eintrag Main-Class
manifest verarbeitet, sodass ein einfaches JAR, das eins definiert, wie ein automatisches Modul gestartet werden kann, in dem die Hauptklasse mit dem Tool jar
festgelegt wurde (dh java --module-path my-app.jar --module my.app
).
Einer der Gründe für die Einführung von Modulen war, das Kompilieren und Starten von Anwendungen zuverlässiger zu machen und Fehler schneller zu finden, als es mit dem Klassenpfad möglich war. Ein kritischer Aspekt davon sind requires
-Klauseln.
Um sie zuverlässig zu halten, gibt es für eine Moduldeklaration keine Möglichkeit, etwas anderes als ein benanntes Modul zu verlangen, das alles aus dem Klassenpfad ausgeschlossene Modul ausschließt. Wenn die Geschichte hier endet, könnte ein modulares JAR nur von anderen modularen JARs abhängen, die das Ökosystem zwingen würden, von Grund auf zu modularisieren.
Das ist jedoch inakzeptabel, also wurden automatische Module als Mittel eingeführt, damit modulare JARs von nicht-modularen JARs abhängen können und alles, was Sie dafür tun müssen, plazieren Sie das einfache JAR auf dem Modulpfad und fordern Sie es mit dem Namen das Modulsystem gibt es.
Das Interessante ist, dass automatische Module das unbenannte Modul lesen, und es ist möglich (und ich empfehle das im Allgemeinen), seine Abhängigkeiten vom Klassenpfad zu lassen. So wirken automatische Module als Brücke vom Modul zum Klassenpfad.
Ihre Module können auf einer Seite sitzen, erfordern ihre direkten Abhängigkeiten als automatische Module, und indirekte Abhängigkeiten können auf der anderen Seite bleiben. Jedes Mal, wenn eine Ihrer Abhängigkeiten zu einem expliziten Modul wird, verlässt sie die Brücke auf der modularen Seite und zieht ihre direkten Abhängigkeiten als automatische Module auf die Brücke.
Ein automatisches Modul ist ein benanntes Modul das ist implizit definiert, seit es keine Moduldeklaration hat. Ein gewöhnliches benanntes Modul, ist dagegen explizit mit einer Moduldeklaration definiert; wir werden beziehen Sie sich fortan auf diese als explizite Module .
Der Hauptvorteil dieser Methoden besteht darin, dass Sie ein Artefakt beim Kompilieren oder Ausführen als Modul behandeln können, ohne darauf zu warten, dass es in die modulare Struktur migriert wird.
Der Modulname eines automatischen Moduls wird von der JAR-Datei abgeleitet, die zum Einschließen des Artefakts verwendet wird, wenn es im Hauptmanifesteintrag das Attribut Automatic-Module-Name aufweist. Der Modulname wird ansonsten vom Namen der JAR-Datei abgeleitet durch ModuleFinder
.
Abgeleitet von der Tatsache, dass das automatische Modul keine Moduldeklaration hat, ist es praktisch nicht möglich zu sagen, was alle Module oder Pakete lesen, öffnen oder exportieren.
➜ Also, da gibt es keine expliziten Exporte / öffnet für Pakete, die sich im automatischen Modul befinden, beschrieben als -
.. keine praktische Möglichkeit zu sagen, welche der Pakete in ein automatisches Modul sind für die Verwendung durch andere Module oder durch Klassen noch auf dem Klassenpfad. Jedes Paket in einem automatischen Modul wird daher als exportiert angesehen, auch wenn es tatsächlich sein könnte nur für den internen Gebrauch gedacht.
➜ Den Link weiter angeben -
... keine praktische Möglichkeit, im Voraus zu sagen, welche anderen Module an Automatisches Modul könnte davon abhängen. Nachdem ein Modulgraph aufgelöst wurde, Daher wird ein automatisches Modul erstellt, um alle anderen Namen zu lesen Modul, ob automatisch oder explizit.
Einer der Vorschläge - Ein automatisches Modul bietet die traditionelle Kapselungsebene: Alle Pakete sind sowohl offen für den reflektiven Tiefenzugriff als auch für den normalen Kompilierungszeit- und Laufzeitzugriff für ihre öffentlichen Typen .
➜ Zusätzlich ein automatisches Modul
gewährt implizite Lesbarkeit für alle anderen automatischen Module
aus dem Grund, dass bei der Verwendung mehrerer automatischer Module in einem Modul sein
.. nicht möglich zu bestimmen, ob einer der exportierten Pakete in einem automatischen Modul (x.y.z) enthält einen Typ, dessen Signatur verweist auf einen Typ, der in einem anderen automatischen Modul (a.b.c) definiert ist.
(Sie scheinen bezüglich einer fehlenden vollständigen Definition recht zu haben, da ich sie in der Sprache oder den JVM-Spezifikationen nicht gefunden habe)
Die Javadocs bieten eine große Menge an formalen Definitionen, obwohl sie in den Paketklassen java.lang.module
enthalten sind.
Teilangebot von Ссылка :
Eine JAR-Datei, die kein
module-info.class
in ihrem obersten Verzeichnis hat, definiert ein automatisches Modul wie folgt:
- Wenn die JAR-Datei das Attribut "
Automatic-Module-Name
" in ihrem Hauptmanifest enthält, ist ihr Wert der Modulname. Der Modulname wird ansonsten vom Namen der JAR-Datei abgeleitet....
Und von Ссылка :
Der Moduldeskriptor für ein automatisches Modul deklariert keine Abhängigkeiten (mit Ausnahme der obligatorischen Abhängigkeit von
java.base
) und deklariert keine exportierten oder offenen Pakete. Automatische Module erhalten während der Auflösung eine spezielle Behandlung, so dass sie alle anderen Module in der Konfiguration lesen. Wenn ein automatisches Modul in der Java Virtual Machine instanziiert wird, liest es jedes unbenannte Modul und wird so behandelt, als ob alle Pakete exportiert und geöffnet wären.
Tags und Links java java-9 jigsaw java-module