web-dev-qa-db-fra.com

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

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 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 compatibilité descendante?

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 Java classes et interfaces; ses données incluent des ressources et d'autres types d'informations statiques.

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

Un package Java est une technique pour organiser les classes Java dans des 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. De 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; dans 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évu.

22
user2418306

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 ex. 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 possède 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 corrigé 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, classes et packages cessent d'être des modules! Un "module" J9 n'est qu'une autre instanciation du module concept. 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. De toute évidence, Java doit conserver son concept de package existant pour une compatibilité ascendante. Notez que le mot "package" est utilisé très différemment dans Java que dans d'autres langues ou dans systèmes de gestion de packages comme RPM. Les nouveaux modules J9 (et les bundles OSGi) ressemblent beaucoup plus à des packages RPM qu'à Java n'ont jamais été.

22
Neil Bartlett

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 en tant que 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 uniques et des contextes de configuration. Malheureusement, cependant, les conventions de package sont facilement contournées, conduisant souvent à un environnement de couplages dangereux au moment de la compilation.

Comme @ser2418306 (OP) laissé entendre, " les modules sont des packages bien faits ". Les modules et 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, elles sont 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. Java package, 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. Par conséquent, les noms de package des classes dans le fichier et leur participation à un chemin de classe sont les seules parties du JAR structure qui confère une modularité à l'environnement d'exécution.


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

Un autre domaine discuté dans cet article sont des systèmes tels que Maven , qui gèrent les dépendances pour vous dans le cadre du processus de construction. 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 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 Ruby's gems , Python's PyPi , et le Node package manager (npm) s'appuient sur cela pour fournir une cohérence façon de configurer un environnement (développement, build, test ou runtime, etc.) avec le bon - stuff (packages, modules, gems, gizmo's, etc.). Une idée (je pense) était " empruntée" à partir de systèmes de distribution Linux® tels que Debian apt , RedHat's rpm, etc. (Bien que, évidemment, a évolué au moins one = génération, et a rendu ces choses plus agréables.)


Java modules, bien qu'ils n'ajoutent pas nécessairement tout ce que vous ne pouvez pas déjà faire, faites tous des outils pour la gestion des dépendances/packages et des environnements de construction automatisés [~ # ~ ] beaucoup [~ # ~] plus facile. Que cela rende les modules "meilleurs", je refuse de le dire. : P

10
Tersosauros