Pourquoi les packages et les modules sont des concepts distincts dans Java 9?

21

Java 9 aura des modules en plus des packages. Habituellement, les langues ont l'une ou l'autre. Et la plupart des programmeurs perçoivent deux termes comme des synonymes. Les modules sont construits sur des packages, les traitant comme des primitives. Le motif composite suggère de traiter les primitives et les composites de manière uniforme. Sinon, de mauvaises choses se produiront. Par exemple, regardez le projet Valhalla, où ils essaient de moderniser le supertype commun pour les types primitifs (valeur) et de référence.

Les modules et les packages représentent-ils des notions sémantiquement distinctes? Cela signifie qu'il est judicieux d'avoir les deux pour n'importe quelle langue (séparation des préoccupations). Ou Java doit-il avoir les deux en hommage à la rétrocompatibilité?

Pourquoi introduire un nouveau concept au lieu d'en augmenter un existant?


JSR 376 : "Système de module de plate-forme Java" implémenté dans le projet Jigsaw .

Selon SOTMS

Un module est une collection nommée et auto-descriptive de code et de données. Son code est organisé comme un ensemble de packages contenant des types, c'est-à-dire des classes et des interfaces Java; ses données comprennent des ressources et d'autres types d'informations statiques.

JLS évite soigneusement de définir ce qu'est un package . De Wikipédia :

Un package Java est une technique pour organiser les classes Java en espaces de noms similaires aux modules de Modula, fournissant une programmation modulaire en Java.

Je sais que citer Wikipédia est une mauvaise pratique, mais cela reflète une compréhension commune. Dès l' entrée sur la programmation modulaire:

Le terme package est parfois utilisé à la place de module (comme dans Dart, Go ou Java). Dans d'autres implémentations, il s'agit d'un concept distinct; en Python, un package est une collection de modules, tandis que dans le prochain Java 9, l'introduction du nouveau concept de module (une collection de packages avec un contrôle d'accès amélioré) est prévue.

user2418306
la source
3
Je pense que vous posez beaucoup de questions ensemble ici? 1) Les modules et packages sont-ils la même idée sémantique? 2) (sinon 1), les jigsawmodules -style sont-ils juste une amélioration technique par rapport aux packages? 3) (sinon 1 et si 2), Java conserve-t-il simplement (ou apparemment) les deux concepts pour une compatibilité descendante. Certaines de ces questions peuvent être résolues, d'autres sont principalement orientées vers l'opinion. Je pense qu'une révision simplifiant les clarifications demandées est de mise ici.
Tersosauros
1
@Tersosauros Vous avez classé "certaines" questions hors sujet, mais vous n'avez pas identifié laquelle est laquelle. Je le vois comme une seule question (1). D'autres seront résolus automatiquement. La compatibilité descendante pour java n'est pas une question. Donc, soit les modules introduits par Java pour corriger les défauts de conception des packages, soit deux notions sont vraiment des préoccupations distinctes. Et la confusion est due à une mauvaise dénomination.
user2418306
1
Je veux clarifier la question. Mais je dois comprendre quelle partie de celui-ci vous semble sans réponse. Quand je pense qu'il n'y a qu'une seule partie.
user2418306
Ahh, je comprends la confusion. Je pense que la question n ° 1 est susceptible de réponse (cette réponse étant "Oui, mais non" - c'est là que la question n ° 3 entre en jeu). Je suis d'accord sur # 3, évidemment Java n'est pas sur le point de changer ce qu'un mot-clé de langue comme packageest / fait / signifie, ni ne changera en (avouons-le, assez horrible) système (s) de chemin de classe dans le JRE. La question n ° 2, je pense, est principalement orientée vers l'opinion (elle peut répondre , mais ma réponse et celle de quelqu'un d'autre peuvent différer et aucun de nous n'aurait nécessairement tort).
Tersosauros
1
Essayez de poser une question claire dès le départ, puis fournissez le matériel d'appui.
Jay Elston

Réponses:

22

Le concept d'un module est différent de l'instanciation de ce concept.

Java a toujours eu des modules. Une méthode est un module, ainsi qu'une classe et un package. Un module est une unité d'organisation dans laquelle les détails internes sont cachés et qui communique avec d'autres modules via des contrats convenus. Par exemple, une méthode est un module car elle a des internes cachés (le code et les variables locales) et un contrat (les paramètres et le type de retour). Les modules peuvent être composés de modules de niveau inférieur, par exemple les classes contiennent des méthodes.

Ce qui manque dans le noyau Java (pré-9) est un module déployable . Tous les types de modules ci-dessus ne sont pas des unités déployables qui peuvent être copiées. Java a un artefact déployable appelé fichier JAR, mais ce ne sont pas des modules car ils n'ont ni encapsulation ni contrat: au moment de l'exécution, les fichiers JAR disparaissent, tous fusionnant dans un seul "chemin de classe".

OSGi a résolu le manque de modules déployables en 1998 avec le concept de «bundle». Il s'agit physiquement de fichiers JAR et ils contiennent des packages, mais OSGi définit des métadonnées supplémentaires ainsi qu'un système d'exécution pour prendre en charge l'encapsulation et les contrats à ce niveau.

Java 9 résout le manque de modules déployables d'une manière similaire à OSGi. On peut dire que cela était complètement inutile car OSGi existe et fonctionne, mais c'est une toute autre discussion ...

Malheureusement, Java 9 brouille les eaux en nommant le nouveau concept de module juste un "module". Cela ne signifie pas que les méthodes, les classes et les packages cessent d'être des modules! Un «module» J9 n'est qu'une autre instanciation du concept de module . Comme les bundles OSGi, les modules J9 sont constitués de packages et ce sont des artefacts physiques (généralement des fichiers JAR à nouveau) qui peuvent être copiés. Le système d'exécution les comprend et les réifie.

Résumé: oui les modules et packages J9 sont des notions sémantiquement distinctes. Évidemment, Java doit conserver son concept de package existant pour une compatibilité descendante. Notez que le mot «package» est utilisé très différemment en Java que dans d'autres langages ou dans des systèmes de gestion de packages comme RPM. Les nouveaux modules J9 (et les bundles OSGi) ressemblent beaucoup plus aux packages RPM que les packages Java ne l'ont jamais été.

Neil Bartlett
la source
Le package ne correspond pas à votre définition d'un module. En raison de la faible encapsulation et du manque de moyens pour regrouper d'autres packages et affiner leur visibilité. Les classes peuvent contenir des classes ou des champs imbriqués. Les méthodes peuvent contenir des fermetures ou appeler d'autres méthodes. Les packages ne peuvent pas "communiquer" avec d'autres packages.
user2418306
Je ne suis pas d'accord. Les packages ont des informations cachées (types d'accès, méthodes et champs par défaut, aka package-private). Les packages "communiquent" certainement car le code d'un package peut invoquer du code dans d'autres packages. Cela se fait contre un contrat, à savoir les types et méthodes publics de l'autre package.
Neil Bartlett
Notez que la possibilité d'agréger des artefacts modulaires au même niveau (par exemple, des méthodes contenant des fermetures, des classes contenant des classes imbriquées) NE fait PAS partie de ma définition d'un module. Si vous considérez que cela fait partie intégrante de la définition du module, les "modules Java 9" ne sont pas non plus des modules.
Neil Bartlett
Je ne nie pas que les paquets ont des informations cachées . J'ai dit que ce n'était pas suffisant. importpeut coupler des packages. Mais il n'y a aucun moyen de structurer des packages en tant que citoyens de première classe. Ces lacunes (et limitations d'OSGi) sont décrites dans JSR 376.
user2418306
Pouvez-vous expliquer pourquoi les modules Java 9 ne sont pas non plus des modules ?
user2418306
10

Permettez-moi de risquer une réponse, bien que cela puisse être en grande partie des hypothèses / des cheveux coupants / des diatribes, etc.

S'agit-il de la même chose? Eh bien, oui et non

De cet article JavaWorld sur "Modularité dans Java 9" :

Les packages comme solution modulaire

Les packages tentent d'ajouter un niveau d'abstraction au paysage de programmation Java. Ils fournissent des installations pour des espaces de noms de codage et des contextes de configuration uniques. Malheureusement, cependant, les conventions de package sont facilement contournées, ce qui conduit fréquemment à un environnement de couplages dangereux au moment de la compilation.

Comme l'indique @ user2418306 (OP) , "les modules sont des packages bien faits " . Les modules et les packages en Java (à partir de Java 9, évidemment) sont (comme OP le demande) sémantiquement la même chose. Autrement dit, ce sont des collections de bytecode JVM précompilé, avec d'autres métadonnées - essentiellement , ce sont des bibliothèques .

Eh bien, quelle est la différence?

Cependant, la différence réside dans les métadonnées à l'intérieur de chacune d'elles. Les packagemanifestes Java ou les manifestes JAR ne sont pas souvent maintenus par les développeurs de bibliothèques, et ils ne fournissent aucun contrat sûr quant à ce que le JAR / package fournit. Comme expliqué ici (article JavaWorld à nouveau) :

Les fichiers JAR ne sont-ils pas suffisamment modulaires?

Les fichiers JAR et l'environnement de déploiement dans lequel ils opèrent améliorent considérablement les nombreuses conventions de déploiement héritées autrement disponibles. Mais les fichiers JAR n'ont pas d'unicité intrinsèque, à part un numéro de version rarement utilisé, qui est caché dans un manifeste .jar. Le fichier JAR et le manifeste facultatif ne sont pas utilisés comme conventions de modularité dans l'environnement d'exécution Java. Ainsi, les noms de package des classes dans le fichier et leur participation à un chemin de classe sont les seules parties de la structure JAR qui confèrent une modularité à l'environnement d'exécution.


Une diatribe sur d'autres langues / environnements, etc.

Un autre domaine abordé dans cet article concerne les systèmes tels que Maven , qui gèrent les dépendances pour vous dans le cadre du processus de génération. De cette page sur le site Apache Maven :

Gestion des dépendances:

Maven encourage l'utilisation d'un référentiel central des fichiers JAR et autres dépendances. Maven est livré avec un mécanisme que les clients de votre projet peuvent utiliser pour télécharger les fichiers JAR nécessaires à la construction de votre projet à partir d'un référentiel JAR central, tout comme le CPAN de Perl. Cela permet aux utilisateurs de Maven de réutiliser les fichiers JAR d'un projet à l'autre et encourage la communication entre les projets pour garantir le traitement des problèmes de compatibilité descendante.

Maintenant, pour parler de l'avenir comme si j'y étais

Comme cette page l'a mentionné, d'autres langues (comme Perl) ont des référentiels de packages (comme CPAN ). C'est une tendance à la hausse (je dis parce que j'en ai envie, sans aucune preuve catégorique), au cours de la dernière décennie environ. Des outils tels que les gemmes de Ruby , PyPi de Python et le gestionnaire de packages Node ( npm) s'appuient sur cela pour fournir un moyen cohérent de configurer un environnement (développement, construction, test ou exécution, etc.) avec les bonnes choses (packages, modules, gemmes, gizmo, etc.). Une idée (je me sens) a été « emprunté » des systèmes de distribution Linux® tels que Debian apt , de RedHatrpm, etc. (Bien que, évidemment, a évolué au moins une génération, et a rendu ces choses plus agréables.)


Java modules , bien qu'ils ne correspondent pas nécessairement tout ce que vous ne pouvez pas le faire déjà, faire l' outillage pour les dépendances / gestion des paquets et des environnements de construction automatisés tout MUCH plus facile. Que cela rende les modules «meilleurs», je refuse de le dire. : P

Tersosauros
la source
1
L'article a seulement 1 an et pourtant déjà obsolète. Il insiste sur le fait que la gestion des versions est une caractéristique fondamentale d'un module. Les modules de scie sauteuse n'auront pas d'informations sur la version. Rien dans le domaine de la gestion des dépendances ne changera pour l'utilisateur final. Pour les outils de construction, les choses deviendront beaucoup plus difficiles en fait. Comme ils doivent supporter des réalités parallèles de classpathet modulepath. Et sautez à travers des cerceaux pour prendre en charge les tests unitaires. Prémisse que deux concepts sont équivalents parce qu'ils représentent une collection de choses plus des métadonnées est trop audacieux pour moi d'accepter. De plus, vous avez soudainement remplacé le pot par le paquet.
user2418306
Je n'ai pas dit " deux concepts sont équivalents ", j'ai dit qu'ils sont "sémantiquement la même chose" - c'est ce que vous avez demandé. En outre, vous avez modifié la question depuis que j'ai répondu pour mentionner spécifiquement JSR-376 , comme opposé au puzzle, ce qui a été dit plus tôt: - /
Tersosauros
La scie sauteuse comprend (met en œuvre) JSR-376. La question est toujours liée aux deux, donc aucun mal n'a été fait. Le dictionnaire définit l'équivalence comme la qualité ou l'état d'avoir la même signification. Et sémantiquement - en ce qui concerne le sens. Je suis désolé, mais vous êtes pédant sur les mauvais détails ici. Vous avez dit qu'ils étaient équivalents. Mais vous n'avez fourni aucun raisonnement. Au lieu de cela, vous vous référez à l'article qui explique comment les packages et les pots ne peuvent pas être des modules. Mais les modules à venir ne sont pas non plus des modules de l'article. Revendiquer l'équivalence et ensuite fournir la différence entre les 2 (3) est contradictoire.
user2418306
La réponse à la question ne peut pas être oui et non. Soit deux concepts sémantiquement équivalents ou non. Veuillez ne pas lobotomiser mes commentaires et revenir à la question d'origine. Un langage a-t-il besoin des deux concepts ou s'agit-il d'un problème spécifique à l'héritage Java? Si vous avez besoin de clarifications, je suis heureux de vous aider.
user2418306