Warum sind Pakete und Module in Java 9 separate Konzepte?

21

Java 9 wird Module zusätzlich zu Paketen enthalten. Normalerweise haben Sprachen die eine oder andere. Und die meisten Programmierer nehmen zwei Begriffe als Synonyme wahr . Module werden auf Paketen aufgebaut und als Grundelemente behandelt. Ein zusammengesetztes Muster legt nahe, Grundelemente und Verbundwerkstoffe gleichmäßig zu behandeln. Sonst passieren schlimme Dinge. Schauen Sie sich zum Beispiel das Projekt Valhalla an, in dem versucht wird, gängige Supertypen für primitive (Wert) und Referenztypen nachzurüsten.

Sind Module und Pakete semantisch getrennte Begriffe? Das heißt, es ist sinnvoll, für jede Sprache beides zu haben (Trennung der Anliegen). Oder muss Java beides als Tribut an die Abwärtskompatibilität haben?

Warum ein neues Konzept einführen, anstatt das bestehende zu erweitern?


JSR 376 : "Java Platform Module System" implementiert im Rahmen des Projekts Jigsaw .

Laut SOTMS

Ein Modul ist eine benannte, selbstbeschreibende Sammlung von Code und Daten. Sein Code ist in Paketen organisiert, die Typen enthalten, dh Java-Klassen und -Schnittstellen. Seine Daten umfassen Ressourcen und andere Arten statischer Informationen.

JLS vermeidet sorgfältig, zu definieren, was ein Paket ist . Aus Wikipedia :

Ein Java-Paket ist eine Technik zum Organisieren von Java-Klassen in Namespaces, die den Modulen von Modula ähneln und eine modulare Programmierung in Java ermöglichen.

Ich weiß, dass das Zitieren von Wikipedia eine schlechte Praxis ist, aber es spiegelt allgemeines Verständnis wider. Vom Einstieg in die modulare Programmierung:

Der Begriff Paket wird manchmal anstelle von Modul verwendet (wie in Dart, Go oder Java). In anderen Implementierungen ist dies ein unterschiedliches Konzept. In Python ist ein Paket eine Sammlung von Modulen, während in Java 9 die Einführung des neuen Modulkonzepts (eine Sammlung von Paketen mit erweiterter Zugriffskontrolle) geplant ist.

user2418306
quelle
3
Ich denke, Sie stellen hier alle zusammen eine Menge Fragen? 1) Sind Module und Pakete die gleiche semantische Idee? 2) (wenn nicht 1), sind jigsaw-Style-Module nur eine technische Verbesserung gegenüber Paketen? 3) (wenn nicht 1 und wenn 2), behält Java einfach (oder scheinbar) beide Konzepte für die Abwärtskompatibilität bei. Einige dieser Fragen sind beantwortbar, andere sind in erster Linie meinungsorientiert. Ich denke, eine Änderung zur Vereinfachung der angestrebten Klarstellung ist hier angebracht.
Tersosauros
1
@Tersosauros Sie haben "einige" Fragen als nicht thematisch eingestuft, aber nicht angegeben, welche Frage welche ist. Ich sehe es als nur eine Frage (1). Andere werden automatisch aufgelöst. Abwärtskompatibilität für Java ist keine Frage. Entweder von Java eingeführte Module, um Designfehler von Paketen zu beheben, oder zwei Begriffe sind wirklich getrennte Anliegen. Und Verwirrung ist auf schlechte Benennung zurückzuführen.
user2418306
1
Ich möchte die Frage klarer stellen. Aber ich muss verstehen, welchen Teil davon Sie für unbeantwortbar halten. Wenn ich denke, gibt es nur einen Teil.
user2418306
Ahh, ich verstehe die Verwirrung. Ich denke, Frage 1 ist beantwortbar (diese Antwort lautet "Ja, aber nein" - hier kommt Nummer 3 ins Spiel). Ich stimme in Punkt 3 zu, offensichtlich wird Java nicht ändern, wie ein Sprachschlüsselwort packagelautet / bedeutet /, und sie werden auch nicht zu (seien wir ehrlich, ziemlich schrecklich) Klassenpfadsystemen in der JRE wechseln. Frage Nr. 2 ist meiner Meinung nach in erster Linie meinungsorientiert (sie ist beantwortbar , aber meine Antwort und die einer anderen Person können sich unterscheiden, und keiner von uns würde sich notwendigerweise irren).
Tersosauros
1
Versuchen Sie, eine klare Frage zu stellen, und geben Sie dann das unterstützende Material an.
Jay Elston

Antworten:

22

Das Konzept eines Moduls unterscheidet sich von der Instanziierung dieses Konzepts.

Java hatte schon immer Module. Eine Methode ist ein Modul, eine Klasse und ein Paket. Ein Modul ist eine Organisationseinheit, in der interne Details verborgen sind und die über vereinbarte Verträge mit anderen Modulen kommuniziert. Eine Methode ist beispielsweise ein Modul, weil sie verborgene Interna (den Code und lokale Variablen) und einen Vertrag (die Parameter und den Rückgabetyp) enthält. Module können aus untergeordneten Modulen zusammengesetzt sein, zB Klassen enthalten Methoden.

Was in Kern-Java (vor 9) fehlt, ist ein implementierbares Modul. Alle oben genannten Modultypen sind keine implementierbaren Einheiten, die kopiert werden können. Java verfügt zwar über ein implementierbares Artefakt, das als JAR-Datei bezeichnet wird, dies sind jedoch keine Module, da sie keine Kapselung oder keinen Vertrag enthalten: Zur Laufzeit verschwinden JAR-Dateien, die alle zu einem einzigen "Klassenpfad" zusammengeführt werden.

OSGi begegnete dem Mangel an implementierbaren Modulen im Jahr 1998 mit dem Konzept eines "Bundles". Dies sind physisch JAR-Dateien und sie enthalten Pakete, aber OSGi definiert zusätzliche Metadaten zusammen mit einem Laufzeitsystem, um die Kapselung und Verträge auf dieser Ebene zu unterstützen.

Java 9 behebt den Mangel an implementierbaren Modulen auf ähnliche Weise wie OSGi. Das war wohl völlig unnötig, weil OSGi existiert und funktioniert, aber das ist eine ganz andere Diskussion ...

Leider trübt Java 9 das Wasser, indem es das neue Modulkonzept nur als "Modul" bezeichnet. Dies bedeutet nicht, dass Methoden, Klassen und Pakete keine Module mehr sind! Ein J9 „Modul“ ist nur eine weitere Instanziierung des Moduls Konzepts . Wie OSGi-Bundles bestehen J9-Module aus Paketen und sind physische Artefakte (normalerweise wieder JAR-Dateien), die kopiert werden können. Das Laufzeitsystem versteht und überprüft sie.

Zusammenfassung: ja J9-Module und -Pakete sind semantisch getrennte Begriffe. Offensichtlich muss Java sein vorhandenes Paketkonzept beibehalten, um die Abwärtskompatibilität zu gewährleisten. Beachten Sie, dass das Wort "package" in Java ganz anders verwendet wird als in anderen Sprachen oder in Paketverwaltungssystemen wie RPM. Die neuen J9-Module (und OSGi-Bundles) ähneln Paketen in RPM weitaus mehr als Java-Pakete.

Neil Bartlett
quelle
Paket entspricht nicht Ihrer Definition eines Moduls. Aufgrund der schwachen Kapselung und des Mangels an Mitteln, um andere Pakete zu aggregieren und ihre Sichtbarkeit zu verfeinern. Klassen können verschachtelte Klassen oder Felder enthalten. Methoden können Closures enthalten oder andere Methoden aufrufen. Pakete können nicht mit anderen Paketen "kommunizieren".
user2418306
Ich stimme dir nicht zu. Pakete haben versteckte Informationen (Standardzugriffstypen, -methoden und -felder, auch bekannt als package-private). Pakete "kommunizieren" mit Sicherheit, da Code in einem Paket Code in anderen Paketen aufrufen kann. Dies erfolgt gegen einen Vertrag, nämlich die öffentlichen Typen und Methoden des anderen Pakets.
Neil Bartlett
Beachten Sie, dass die Fähigkeit, modulare Artefakte auf derselben Ebene zu aggregieren (z. B. Methoden, die Abschlüsse enthalten, Klassen, die verschachtelte Klassen enthalten), NICHT Teil meiner Definition eines Moduls ist. Wenn Sie dies für einen notwendigen Bestandteil der Moduldefinition halten, sind "Java 9-Module" ebenfalls keine Module.
Neil Bartlett
Ich leugne nicht, dass sich in Paketen Informationen verstecken . Ich sagte, dass es nicht ausreicht. importkann Pakete koppeln. Es gibt jedoch keine Möglichkeit, Pakete als Bürger erster Klasse zu strukturieren. Diese Mängel (und Einschränkungen von OSGi) sind in JSR 376 beschrieben.
user2418306
Können Sie erläutern, warum Java 9-Module auch keine Module sind ?
user2418306
10

Lassen Sie mich bei einer Antwort riskieren, auch wenn viele davon Vermutungen / Haarspalterei / Schimpfen usw. sein mögen.

Sind sie dasselbe? Nun, ja und nein

Aus diesem JavaWorld-Artikel über "Modularität in Java 9" :

Pakete als modulare Lösung

Pakete versuchen, der Java-Programmierlandschaft eine Abstraktionsebene hinzuzufügen. Sie bieten Funktionen für eindeutige Codierungsnamespaces und Konfigurationskontexte. Leider können Paketkonventionen leicht umgangen werden, was häufig zu gefährlichen Kopplungen während der Kompilierungszeit führt.

Wie @ user2418306 (OP) andeutete, sind " Module richtig gemachte Pakete " . Module und Pakete in Java (ab Java 9 natürlich) sind (wie OP fragt) semantisch dasselbe. Das heißt, es handelt sich um Sammlungen von vorkompiliertem JVM-Bytecode mit anderen Metadaten - im Wesentlichen handelt es sich um Bibliotheken .

Was ist der Unterschied?

Der Unterschied liegt jedoch in den Metadaten in jedem von ihnen. Java- packageManifeste oder JAR-Manifeste werden von Bibliotheksentwicklern häufig nicht verwaltet und bieten auch keinen sicheren Vertrag darüber, was die JAR / das Paket bereitstellt. Wie hier erklärt (JavaWorld-Artikel erneut) :

Sind JAR-Dateien nicht modular genug?

JAR-Dateien und die Implementierungsumgebung, in der sie ausgeführt werden, verbessern die vielen ansonsten verfügbaren herkömmlichen Implementierungskonventionen erheblich. JAR-Dateien weisen jedoch keine intrinsische Einzigartigkeit auf, abgesehen von einer selten verwendeten Versionsnummer, die in einem JAR-Manifest verborgen ist. Die JAR-Datei und das optionale Manifest werden in der Java-Laufzeitumgebung nicht als Modularitätskonventionen verwendet. Daher sind die Paketnamen der Klassen in der Datei und ihre Teilnahme an einem Klassenpfad die einzigen Teile der JAR-Struktur, die der Laufzeitumgebung Modularität verleihen.


Eine Schimpfe über andere Sprachen / Umgebungen usw

Ein weiterer in diesem Artikel behandelter Bereich sind Systeme wie Maven , die Abhängigkeiten für Sie als Teil des Erstellungsprozesses verwalten. Von dieser Seite auf der Apache Maven-Site :

Abhängigkeitsmanagement:

Maven empfiehlt die Verwendung eines zentralen Repositorys für JARs und andere Abhängigkeiten. Maven wird mit einem Mechanismus geliefert, mit dem die Kunden Ihres Projekts alle für die Erstellung Ihres Projekts erforderlichen JARs aus einem zentralen JAR-Repository herunterladen können, ähnlich dem CPAN von Perl. Auf diese Weise können Benutzer von Maven JARs projektübergreifend wiederverwenden und die Kommunikation zwischen Projekten fördern, um sicherzustellen, dass Probleme mit der Abwärtskompatibilität behoben werden.

Nun, um über die Zukunft zu sprechen, als wäre ich dort gewesen

Wie auf dieser Seite bereits erwähnt, verfügen andere Sprachen (wie Perl) über Paket-Repositorys (wie CPAN ). Dies ist ein zunehmender Trend (ich sage, weil ich das Gefühl habe, ohne jeden nachdrücklichen Beweis) im letzten Jahrzehnt oder so. Tools wie Ruby Edelsteine , Pythons PyPI und der Knoten Paket - Manager ( npm) als Grundlage für eine konsistente Art und Weise , um eine Umgebung zu konfigurieren (entweder Entwicklung, Build, Test oder Laufzeit, usw.) mit dem richtigen Material (Pakete, Module, Edelsteine, Gizmos usw.). Eine Idee (ich fühle mich) wurde ausgeliehen von Linux® Verteilungssysteme wie Debians apt , RedHatsrpm, etc. (Obwohl sich offensichtlich mindestens eine Generation weiterentwickelt hat und all diese Dinge schöner gemacht hat.)


Java- Module fügen zwar nicht notwendigerweise etwas hinzu, was Sie noch nicht tun können, vereinfachen jedoch das Tooling für Abhängigkeiten / Paketverwaltung und automatisierte Build-Umgebungen VIEL . Ob das Module "besser" macht, möchte ich nicht sagen. : P

Tersosauros
quelle
1
Artikel ist erst 1 Jahr alt und doch schon veraltet. Es wird erläutert, wie die Versionierung ein grundlegendes Merkmal eines Moduls ist. Jigsaw-Module haben keine Versionsinformationen. Für den Endbenutzer ändert sich nichts im Bereich der Abhängigkeitsverwaltung. Für Build-Tools wird es in der Tat viel schwieriger. Da müssen sie parallele Realitäten von classpathund unterstützen modulepath. Und springen Sie durch die Reifen, um das Testen von Einheiten zu unterstützen. Die Annahme, dass zwei Konzepte gleichwertig sind, weil sie eine Sammlung von Dingen und Metadaten darstellen, ist zu kühn, als dass ich sie akzeptieren würde. In der Zwischenzeit haben Sie das Paket durch ein Glas ersetzt.
user2418306
Ich habe nicht gesagt, dass " zwei Konzepte gleichwertig sind ", sondern dass sie "semantisch dasselbe" sind - und danach haben Sie gefragt. Außerdem haben Sie die Frage bearbeitet , da ich beantworten speziell JSR-376 zu nennen , widersetzt, zu Puzzle , das , was gesagt wurde früher: - /
Tersosauros
Stichsäge umfasst (implementiert) JSR-376. Die Frage ist immer noch mit beiden verknüpft, daher wurde kein Schaden angerichtet. Das Wörterbuch definiert Äquivalenz als die Qualität oder den Zustand derselben Bedeutung. Und semantisch - in Bezug auf die Bedeutung. Es tut mir leid, aber Sie sind über falsche Details hier pedantisch. Sie haben gesagt, sie sind gleichwertig. Aber Sie haben keine Begründung geliefert. Stattdessen verweisen Sie auf den Artikel, in dem erläutert wird, wie Pakete und Jars nicht zu Modulen werden. Kommende Module sind jedoch keine Module aus dem Artikel. Es ist widersprüchlich, die Äquivalenz zu beanspruchen und dann die Differenz zwischen 2 (3) zu schaffen.
user2418306
Die Antwort auf die Frage kann nicht Ja und Nein sein. Entweder zwei Konzepte, die semantisch äquivalent sind oder nicht. Bitte lobotomisieren Sie meine Kommentare nicht und kehren Sie zur ursprünglichen Frage zurück. Benötigt eine Sprache beide Konzepte oder handelt es sich um ein spezifisches Java-Legacy-Problem? Wenn Sie Klarstellungen benötigen, helfe ich Ihnen gerne weiter.
user2418306