web-dev-qa-db-fra.com

Pourquoi projeter Jigsaw / JPMS?

Le système de gestion des packages de Java m'a toujours semblé simple et efficace. Il est largement utilisé par le JDK lui-même. Nous l'avons utilisé pour imiter le concept d'espaces de noms et de modules.

Qu'est-ce que Jigsaw Project (aka Java Platform Module System ) essaie de remplir?

Depuis le site officiel:

Le but de ce projet est de concevoir et de mettre en œuvre un système de modules standard pour la plate-forme Java SE) et d'appliquer ce système à la plate-forme elle-même et au JDK.

78
John

Jigsaw et OSGi tentent de résoudre le même problème: comment permettre aux modules plus grossiers d'interagir tout en protégeant leurs composants internes.

Dans le cas de Jigsaw, les modules à granularité plus grossière incluent Java classes, packages et leurs dépendances).

Voici un exemple: Spring et Hibernate. Les deux ont une dépendance sur un JAR CGLIB tiers, mais ils utilisent des versions différentes et incompatibles de ce JAR. Que pouvez-vous faire si vous comptez sur le JDK standard? Y compris la version que Spring veut casser Hibernate et vice versa.

Mais, si vous avez un modèle de niveau supérieur comme Jigsaw, vous pouvez facilement gérer différentes versions d'un JAR dans différents modules. Considérez-les comme des packages de niveau supérieur.

Si vous construisez Spring à partir de la source GitHub vous le verrez aussi. Ils ont refait le cadre de sorte qu'il se compose de plusieurs modules: noyau, persistance, etc. Vous pouvez choisir et choisir l'ensemble minimal de dépendances de module dont votre application a besoin et ignorer le reste. Auparavant, il s'agissait d'un seul fichier Spring JAR contenant tous les fichiers .class.

Mise à jour: cinq ans plus tard - Jigsaw pourrait encore avoir problèmes à résoudre.

100
duffymo

AFAIK L'objectif est de rendre le JRE plus modulaire. C'est à dire. ont des pots plus petits qui sont facultatifs et/ou vous pouvez télécharger/mettre à niveau uniquement les fonctionnalités dont vous avez besoin.

C'est pour le rendre moins gonflé et vous donner la possibilité de supprimer les modules hérités que la plupart des gens n'utilisent peut-être pas.

43
Peter Lawrey

Basé sur Mark Reinholddiscours d'ouverture à Devoxx Belgique , Project Jigsaw va aborder deux points principaux:

  1. Chemin de classe
  2. JDK monolithique massif

Quel est le problème avec Classpath?


Nous connaissons tous le JAR Hell . Ce terme décrit toutes les différentes manières dont le processus classloading peut finir par ne pas fonctionner. Les limitations les plus connues de classpath sont:

  • Il est difficile de dire s'il y a des conflits. les outils de construction comme maven peuvent faire un très bon travail basé sur les noms d'artefacts mais si les artefacts eux-mêmes ont des noms différents mais le même contenu, il pourrait y avoir un conflit.
  • Le problème fondamental avec les fichiers jar est qu'ils ne sont pas des composants. Ce ne sont que des tas de conteneurs de fichiers qui seront recherchés de façon linéaire. Classpath est un moyen de rechercher des classes quels que soient les composants dans lesquels ils se trouvent, les packages dans lesquels ils se trouvent ou leur utilisation prévue.

JDK monolithique massif


La grande nature monolithique de JDK pose plusieurs problèmes:

  • Il ne convient pas aux petits appareils. Même si les petits appareils de type IoT ont des processeurs capables d'exécuter une classe SE VM mais ils n'ont pas nécessairement la mémoire pour contenir tout le JDK, en particulier, lorsque l'application n'en utilise qu'une petite partie .
  • C'est même un problème dans le Cloud. Le cloud consiste à optimiser l'utilisation du matériel, si vous avez des milliers d'images contenant l'intégralité du JDK mais que les applications n'en utilisent qu'une petite partie, ce serait un gaspillage.

Modules: la solution commune


Pour résoudre les problèmes ci-dessus, nous traitons les modules comme un nouveau type fondamental de composant de programme Java. 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.

Pour contrôler la façon dont son code fait référence aux types dans d'autres modules, un module déclare les autres modules dont il a besoin pour être compilé et exécuté. Pour contrôler la façon dont le code des autres modules fait référence aux types dans ses packages, un module déclare lequel de ces packages il exporte.

Le système de modules localise les modules requis et, contrairement au mécanisme de chemin de classe, garantit que le code dans un module ne peut se référer qu'aux types des modules dont il dépend. Les mécanismes de contrôle d'accès du langage Java et de la machine virtuelle Java) empêchent le code d'accéder aux types dans les packages qui ne sont pas exportés par leurs modules de définition.

En plus d'être plus fiable, la modularité pourrait améliorer les performances. Lorsque le code dans un module fait référence à un type dans un package, ce package est garanti d'être défini soit dans ce module, soit précisément dans l'un des modules lus par ce module. Lors de la recherche de la définition d'un type spécifique, il n'est donc pas nécessaire de la rechercher dans plusieurs modules ou, pire, tout au long du chemin de classe.

JEP à suivre


Jigsaw est un énorme projet qui se poursuit depuis plusieurs années. Il a une quantité impressionnante de JEP qui sont d'excellents endroits pour obtenir plus d'informations sur le projet. Certains de ces JEP sont les suivants:

  • JEP 200: le JDK modulaire : Utilisez le Java Platform Module System (JPMS) pour modulariser le JDK
  • JEP 201: Modular Source Code : Réorganisez le code source JDK en modules, améliorez le système de construction pour compiler les modules et imposez les limites des modules au moment de la construction
  • JEP 261: Module System : Implémentez le Java Platform Module System, comme spécifié par JSR 376, avec les modifications et améliorations spécifiques au JDK
  • JEP 220: Images d'exécution modulaires : Restructurez les images d'exécution JDK et JRE pour accueillir les modules et améliorer les performances, la sécurité et la maintenabilité
  • JEP 260: encapsuler la plupart des API internes : Rendre la plupart des API internes du JDK inaccessibles par défaut, mais laisser quelques API internes critiques et largement utilisées accessibles, jusqu'à ce que des remplacements pris en charge existent pour tous ou pour la plupart de leurs fonctionnalités
  • JEP 282: jlink: Le Java Linker : Créer un outil qui peut assembler et optimiser un ensemble de modules et leurs dépendances dans un run-time personnalisé image telle que définie dans JEP 22

Remarques de clôture


Dans l'édition initiale du rapport L'état du système de modules , Mark Reinhold décrit les objectifs spécifiques du système de modules comme suit:

  • Configuration fiable , pour remplacer le mécanisme de chemin de classe fragile et sujet aux erreurs par un moyen pour les composants du programme de déclarer des dépendances explicites les uns des autres, ainsi que
  • Encapsulation forte , pour permettre à un composant de déclarer lesquels de ses types publics sont accessibles aux autres composants, et lesquels ne le sont pas.

Ces fonctionnalités profiteront aux développeurs d'applications, aux développeurs de bibliothèques et aux implémenteurs de la plate-forme Java SE elle-même directement et indirectement, car elles permettront une plate-forme évolutive, une plus grande intégrité de la plate-forme et des performances améliorées.

42
Ali Dehghani

Pour les besoins de l'argument, affirmons que Java 8 (et versions antérieures) a déjà une "forme" de modules (jars) et de système de modules (le chemin de classe ). Mais ces problèmes sont bien connus.

En examinant les problèmes, nous pouvons illustrer la motivation de Jigsaw. (Ce qui suit suppose que nous n'utilisons pas les modules OSGi, JBoss, etc., qui offrent certainement des solutions.)

Problème 1: public est aussi public

Considérez les classes suivantes (supposez que les deux sont publiques):

com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl

Chez Foo.com, nous pourrions décider que notre équipe devrait utiliser UserDao et non pas UserDaoImpl directement. Cependant, il n'y a aucun moyen d'imposer cela sur le chemin de classe.

Dans Jigsaw, un module contient un module-info.Java fichier qui nous permet de déclarer explicitement ce qui est public pour les autres modules. Autrement dit, le public a des nuances. Par exemple:

// 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;
}

Problème 2: la réflexion est débridée

Étant donné les classes de # 1, quelqu'un pourrait toujours le faire en Java 8:

Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();

C'est-à-dire que la réflexion est puissante et essentielle, mais si elle n'est pas cochée, elle peut être utilisée pour pénétrer dans les internes d'un module de manière indésirable. Mark Reinhold a plutôt un exemple alarmant . (Le message SO est ici .)

Dans Jigsaw, encapsulation forte offre la possibilité de refuser l'accès à une classe, y compris la réflexion. (Cela peut dépendre des paramètres de ligne de commande, dans l'attente de la spécification technique révisée pour JDK 9.) Notez que parce que Jigsaw est utilisé pour le JDK lui-même, Oracle prétend que cela permettra à l'équipe Java innover plus rapidement les plateformes internes.

Problème 3: le chemin de classe efface les relations architecturales

Une équipe a généralement un modèle mental sur les relations entre les pots. Par exemple, foo-app.jar peut utiliser foo-services.jar qui utilise foo-db.jar. On pourrait affirmer que les classes dans foo-app.jar ne doit pas contourner "la couche de service" et utiliser foo-db.jar directement. Cependant, il n'y a aucun moyen de l'imposer via le chemin de classe. Mark Reinhold mentionne ceci ici .

En comparaison, Jigsaw propose un modèle d'accessibilité explicite et fiable pour les modules.

Problème 4: exécution monolithique

Le Java runtime est dans le monolithique rt.jar. Sur ma machine, c'est 60+ MB avec 20k classes! À l'ère des micro-services, des appareils IoT, etc., il n'est pas souhaitable d'avoir Corba, Swing, XML et d'autres bibliothèques sur disque si elles ne sont pas utilisées.

Jigsaw décompose le JDK lui-même en plusieurs modules; par exemple. Java.sql contient les classes SQL familières. Il y a plusieurs avantages à cela, mais un nouveau est l'outil jlink. En supposant qu'une application est complètement modularisée, jlink génère un image d'exécution distribuable qui est coupé pour contenir uniquement les modules spécifiés (et leurs dépendances). Pour l'avenir, Oracle envisage un avenir où les modules JDK sont compilés à l'avance en code natif. Bien que jlink soit facultatif et que la compilation AOT soit expérimentale, ce sont des indications majeures de l'orientation d'Oracle.

Problème 5: versioning

Il est bien connu que le chemin de classe ne nous permet pas d'utiliser plusieurs versions du même pot: par ex. bar-lib-1.1.jar et bar-lib-2.2.jar.

Jigsaw ne résout pas ce problème; Mark Reinhold déclare le justification ici . L'essentiel est que Maven, Gradle et d'autres outils représentent un vaste écosystème pour la gestion des dépendances, et une autre solution sera plus nuisible que bénéfique.

Il convient de noter que d'autres solutions (par exemple OSGi) résolvent effectivement ce problème (et d'autres, à part le n ° 4).

Conclusion

Voilà quelques points clés pour Jigsaw, motivés par des problèmes spécifiques.

Notez que l'explication de la controverse entre Jigsaw, OSGi, JBoss Modules, etc. est une discussion distincte qui appartient à un autre site Stack Exchange. Il existe beaucoup plus de différences entre les solutions que celles décrites ici. De plus, il y avait un consensus suffisant pour approuver le scrutin de réexamen public pour JSR 376.

13
Michael Easter

Cet article explique en détail les problèmes que OSGi et JPMS/Jigsaw tentent de résoudre:

"Java 9, OSGi et l'avenir de la modularité" [22 SEP 2016]

Il va également à fond dans les approches d'OSGi et de JPMS/Jigsaw. À l'heure actuelle, il semble que les auteurs n'aient répertorié pratiquement aucun avantage pratique pour JPMS/Jigsaw par rapport à l'OSGi mature (16 ans).

3
uvsmtid