Jigsaw und OSGi versuchen, dasselbe Problem zu lösen: Wie können gröberkörnige Module interagieren und gleichzeitig ihre Interna abgeschirmt werden?
In Jigsaws Fall enthalten die gröberkörnigen Module Java-Klassen, -Pakete und deren Abhängigkeiten.
Hier ist ein Beispiel: Frühling und Winterschlaf. Beide sind von einer JAR-CGLIB eines Drittanbieters abhängig, verwenden jedoch unterschiedliche, inkompatible Versionen dieser JAR. Was können Sie tun, wenn Sie sich auf das Standard-JDK verlassen? Einschließlich der Version, die Spring will, bricht der Ruhezustand und umgekehrt.
Wenn Sie jedoch ein übergeordnetes Modell wie Jigsaw haben, können Sie problemlos verschiedene Versionen einer JAR in verschiedenen Modulen verwalten. Stellen Sie sich diese als übergeordnete Pakete vor.
Wenn Sie Spring aus der GitHub-Quelle erstellen, sehen Sie es auch. Sie haben das Framework überarbeitet, sodass es aus mehreren Modulen besteht: Kern, Persistenz usw. Sie können die minimalen Modulabhängigkeiten auswählen, die Ihre Anwendung benötigt, und den Rest ignorieren. Früher war es eine einzelne Spring-JAR mit allen darin enthaltenen .class-Dateien.
Update: Fünf Jahre später - Jigsaw muss möglicherweise noch einige Probleme lösen.
AFAIK Der Plan ist, die JRE modularer zu gestalten. Dh haben kleinere Gläser, die optional sind und / oder Sie können nur die Funktionalität herunterladen / aktualisieren, die Sie benötigen.
Dies soll die Aufblähung verringern und Ihnen die Möglichkeit geben, ältere Module zu löschen, die die meisten Benutzer möglicherweise nicht verwenden.
quelle
import
verwenden, wird diese Klasse lediglich in den Namensraum der Klasse für den Compiler eingeführt. Wenn Sie es nicht verwenden, wird es nicht im erstellten Bytecode angezeigt. Wenn Sie die Klasse tatsächlich verwenden, benötigen Sie diese Klasse und jede Klasse, die sie zur Laufzeit verwendet. Theoretisch könnten Sie eine abgespeckte Version der Guava-API erstellen, die nur das enthält, was Sie benötigen, und stattdessen diese JAR verwenden. In der Realität ist dies fehleranfällig und in den meisten Fällen nicht sehr nützlich, und Sie fügen am Ende nur die gesamte JAR hinzu, wie sie freigegeben wurde.Basierend auf Mark Reinhold ‚s Keynote auf Devoxx Belgien , Projekt Jigsaw wird zu Adresse zwei Hauptschmerzpunkte:
Was ist los mit Classpath?
Wir alle kennen die JAR-Hölle . Dieser Begriff beschreibt die verschiedenen Möglichkeiten, mit denen der Klassenladevorgang möglicherweise nicht funktioniert. Die bekanntesten Einschränkungen von classpath sind:
Massives monolithisches JDK
Die große monolithische Natur von JDK verursacht mehrere Probleme:
Module: Die gemeinsame Lösung
Um die oben genannten Probleme zu lösen, behandeln wir Module als eine grundlegende neue Art von Java-Programmkomponente. Ein Modul ist eine benannte, selbstbeschreibende Sammlung von Code und Daten. Sein Code ist als eine Reihe von Paketen organisiert, die Typen enthalten, dh Java-Klassen und -Schnittstellen. Die Daten umfassen Ressourcen und andere Arten statischer Informationen.
Um zu steuern, wie sich der Code auf Typen in anderen Modulen bezieht, gibt ein Modul an, welche anderen Module es zum Kompilieren und Ausführen benötigt. Um zu steuern, wie Code in anderen Modulen auf Typen in seinen Paketen verweist, gibt ein Modul an, welches dieser Pakete es exportiert.
Das Modulsystem lokalisiert die erforderlichen Module und stellt im Gegensatz zum Klassenpfadmechanismus sicher, dass der Code in einem Modul nur auf Typen in den Modulen verweisen kann, von denen er abhängt. Die Zugriffssteuerungsmechanismen der Java-Sprache und der Java Virtual Machine verhindern, dass Code auf Typen in Paketen zugreift, die nicht von ihren definierenden Modulen exportiert werden.
Modularität ist nicht nur zuverlässiger, sondern kann auch die Leistung verbessern. Wenn sich Code in einem Modul auf einen Typ in einem Paket bezieht, wird dieses Paket garantiert entweder in diesem Modul oder in genau einem der von diesem Modul gelesenen Module definiert. Wenn Sie nach der Definition eines bestimmten Typs suchen, müssen Sie daher nicht in mehreren Modulen oder, schlimmer noch, entlang des gesamten Klassenpfads danach suchen.
JEPs folgen
Jigsaw ist ein riesiges Projekt, das seit einigen Jahren läuft. Es gibt eine beeindruckende Anzahl von JEPs, die großartige Orte sind, um mehr Informationen über das Projekt zu erhalten. Einige dieser JEPs sind wie folgt:
Schlußbemerkungen
In der ersten Ausgabe des Berichts über den Status des Modulsystems beschreibt Mark Reinhold die spezifischen Ziele des Modulsystems wie folgt:
Diese Funktionen kommen Anwendungsentwicklern, Bibliotheksentwicklern und Implementierern der Java SE-Plattform selbst direkt und indirekt zugute, da sie eine skalierbare Plattform, eine größere Plattformintegrität und eine verbesserte Leistung ermöglichen.
quelle
Nehmen wir aus Gründen der Argumentation an, dass Java 8 (und früher) bereits eine "Form" von Modulen (Jars) und Modulsystem (Klassenpfad) hat. Es gibt jedoch bekannte Probleme mit diesen.
Indem wir die Probleme untersuchen, können wir die Motivation für Jigsaw veranschaulichen. (Im Folgenden wird davon ausgegangen, dass wir keine OSGi, JBoss-Module usw. verwenden, die mit Sicherheit Lösungen bieten.)
Problem 1: Öffentlichkeit ist zu öffentlich
Betrachten Sie die folgenden Klassen (vorausgesetzt, beide sind öffentlich):
Bei Foo.com entscheiden wir möglicherweise, dass unser Team verwenden
UserDao
und nichtUserDaoImpl
direkt verwenden soll. Es gibt jedoch keine Möglichkeit, dies im Klassenpfad durchzusetzen.In Jigsaw enthält ein Modul eine
module-info.java
Datei, mit der wir explizit angeben können, was für andere Module öffentlich ist. Das heißt, die Öffentlichkeit hat Nuancen. Zum Beispiel:// com.acme.foo.db.api.UserDao is accessible, but // com.acme.foo.db.impl.UserDaoImpl is not module com.acme.foo.db { exports com.acme.foo.db.api; }
Problem 2: Reflexion ist ungezügelt
Angesichts der Klassen in # 1 könnte jemand dies in Java 8 noch tun:
Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl"); Object obj = c.getConstructor().newInstance();
Das heißt: Reflexion ist mächtig und wesentlich, aber wenn sie nicht aktiviert ist, kann sie verwendet werden, um auf unerwünschte Weise in die Interna eines Moduls zu gelangen. Mark Reinhold hat ein ziemlich alarmierendes Beispiel . (Der SO-Beitrag ist hier .)
In Jigsaw bietet eine starke Kapselung die Möglichkeit, den Zugriff auf eine Klasse einschließlich Reflexion zu verweigern. (Dies kann von den Befehlszeileneinstellungen abhängen, bis die überarbeitete technische Spezifikation für JDK 9 vorliegt.) Da Jigsaw für das JDK selbst verwendet wird, behauptet Oracle, dass das Java-Team dadurch die Plattforminternale schneller innovieren kann.
Problem 3: Der Klassenpfad löscht architektonische Beziehungen
Ein Team hat normalerweise ein mentales Modell für die Beziehungen zwischen Gläsern. Zum Beispiel
foo-app.jar
kann verwenden,foo-services.jar
welche Verwendungenfoo-db.jar
. Wir könnten behaupten, dass Klassen infoo-app.jar
"die Serviceschicht" nicht umgehen undfoo-db.jar
direkt verwenden sollten. Es gibt jedoch keine Möglichkeit, dies über den Klassenpfad zu erzwingen. Mark Reinhold erwähnt dies hier .Im Vergleich dazu bietet Jigsaw ein explizites, zuverlässiges Barrierefreiheitsmodell für Module.
Problem 4: monolithische Laufzeit
Die Java-Laufzeit ist monolithisch
rt.jar
. Auf meinem Computer sind es mehr als 60 MB mit 20.000 Klassen! In Zeiten von Mikrodiensten, IoT-Geräten usw. ist es unerwünscht, Corba, Swing, XML und andere Bibliotheken auf der Festplatte zu haben, wenn sie nicht verwendet werden.Jigsaw unterteilt das JDK selbst in viele Module. zB java.sql enthält die bekannten SQL - Klassen. Dies hat mehrere Vorteile, aber ein neuer ist das
jlink
Werkzeug. Angenommen, eine App ist vollständig modularisiert,jlink
wird ein verteilbares Laufzeit-Image generiert , das so beschnitten ist, dass es nur die angegebenen Module (und ihre Abhängigkeiten) enthält. Mit Blick auf die Zukunft sieht Oracle eine Zukunft vor, in der die JDK-Module vorab zu nativem Code kompiliert werden. Obwohl diesjlink
optional ist und die AOT-Kompilierung experimentell ist, sind sie wichtige Hinweise darauf, wohin Oracle steuert.Problem 5: Versionierung
Es ist bekannt, dass der Klassenpfad es uns nicht erlaubt, mehrere Versionen desselben JARs zu verwenden: zB
bar-lib-1.1.jar
undbar-lib-2.2.jar
.Jigsaw geht dieses Problem nicht an. Mark Reinhold gibt hier die Gründe an . Das Wesentliche ist, dass Maven, Gradle und andere Tools ein großes Ökosystem für das Abhängigkeitsmanagement darstellen und eine andere Lösung eher schädlich als nützlich ist.
Es sollte beachtet werden, dass andere Lösungen (z. B. OSGi) dieses Problem tatsächlich angehen (und andere, abgesehen von # 4).
Endeffekt
Das sind einige wichtige Punkte für Jigsaw, die durch spezifische Probleme motiviert sind.
Beachten Sie, dass das Erklären der Kontroverse zwischen Jigsaw-, OSGi-, JBoss-Modulen usw. eine separate Diskussion ist, die zu einer anderen Stack Exchange-Site gehört. Es gibt viel mehr Unterschiede zwischen den Lösungen als hier beschrieben. Darüber hinaus bestand ein ausreichender Konsens, um den Stimmzettel zur Überprüfung der öffentlichen Überprüfung für JSR 376 zu genehmigen .
quelle
In diesem Artikel werden die Probleme, die sowohl OSGi als auch JPMS / Jigsaw zu lösen versuchen, ausführlich erläutert:
"Java 9, OSGi und die Zukunft der Modularität" [22. September 2016]
Es wird auch ausführlich auf die Ansätze von OSGi und JPMS / Jigsaw eingegangen. Derzeit scheinen die Autoren im Vergleich zu gereiftem (16 Jahre alt) OSGi fast keine praktischen Vorteile für JPMS / Jigsaw aufgeführt zu haben.
quelle