Lorsque vous écrivez du code pour des projets réels, ils sont beaucoup plus volumineux. Un vrai projet se compose de centaines ou de milliers de classes regroupées en packages. Ces packages sont regroupés dans des fichiers d’archive Java (JAR). Un JAR est un fichier ZIP avec quelques informations supplémentaires, et l’extension est .jar
.
En plus du code écrit par votre équipe, la plupart des applications utilisent également du code écrit par d’autres. Open source est un logiciel dont le code est fourni et souvent gratuit à utiliser. Java possède une communauté de logiciels open source (OSS) dynamique, et ces bibliothèques sont également fournies sous forme de fichiers JAR. Par exemple, il existe des bibliothèques pour lire des fichiers, se connecter à une base de données, et bien plus encore.
Certains projets open source dépendent même de fonctionnalités d’autres projets open source. Par exemple, Spring est un framework couramment utilisé, et JUnit est une bibliothèque de test couramment utilisée. Pour utiliser l’un ou l’autre, vous devez vous assurer que vous disposez de versions compatibles de tous les JAR pertinents disponibles au moment de l’exécution. Cette chaîne complexe de dépendances et de versions minimales est souvent appelée JAR hell par la communauté. L’enfer est une excellente façon de décrire le chargement de la mauvaise version d’une classe ou même une ClassNotFoundException
au moment de l’exécution.
Le Java Platform Module System (JPMS) regroupe le code à un niveau supérieur. L’objectif principal d’un module est de fournir des groupes de packages connexes qui offrent aux développeurs un ensemble particulier de fonctionnalités. C’est comme un fichier JAR, sauf qu’un développeur choisit quels packages sont accessibles en dehors du module. Examinons ce que sont les modules et quels problèmes ils sont conçus pour résoudre.
Le Java Platform Module System comprend les éléments suivants :
- Un format pour les fichiers JAR de module
- Partitionnement du JDK en modules
- Options de ligne de commande supplémentaires pour les outils Java
Explorer un Module
Dans “Building Blocks”, nous avions une petite application Zoo. Elle n’avait qu’une seule classe et imprimait juste une chose. Maintenant, imaginez que nous avions toute une équipe de programmeurs et que nous automatisions les opérations du zoo. De nombreuses choses doivent être codées, y compris les interactions avec les animaux, les visiteurs, le site web public et les activités de sensibilisation.
Un module est un groupe d’un ou plusieurs packages plus un fichier spécial appelé module-info.java
. Le contenu de ce fichier est la déclaration de module. La figure 12.1 répertorie quelques-uns des modules dont un zoo pourrait avoir besoin. Nous avons décidé de nous concentrer sur les interactions avec les animaux dans notre exemple. Le zoo complet pourrait facilement avoir une douzaine de modules. Dans la figure 12.1, notez qu’il y a des flèches entre plusieurs modules. Celles-ci représentent des dépendances, où un module s’appuie sur le code d’un autre. Le personnel doit nourrir les animaux pour conserver leurs emplois. La ligne de zoo.staff
à zoo.animal.feeding
montre que le premier dépend du second.
Maintenant, explorons un de ces modules en détail. La figure 12.2 montre ce qui se trouve à l’intérieur du module zoo.animal.talks
. Il y a trois packages avec deux classes chacun. (C’est un petit zoo.) Il y a aussi un fichier étrange appelé module-info.java
. Ce fichier est requis dans tous les modules. Nous expliquons cela plus en détail plus loin dans le chapitre.
Avantages des Modules
Les modules ressemblent à une couche supplémentaire de choses que vous devez connaître pour programmer. Bien que l’utilisation des modules soit facultative, il est important de comprendre les problèmes qu’ils sont conçus pour résoudre :
- Meilleur contrôle d’accès : En plus des niveaux de contrôle d’accès, vous pouvez avoir des packages qui ne sont accessibles qu’à d’autres packages dans le module.
- Gestion des dépendances plus claire : Puisque les modules spécifient ce sur quoi ils s’appuient, Java peut se plaindre d’un JAR manquant lors du démarrage du programme plutôt que lorsqu’il est accédé pour la première fois à l’exécution.
- Builds Java personnalisés : Vous pouvez créer un runtime Java qui n’a que les parties du JDK dont votre programme a besoin plutôt que la version complète de plus de 150 Mo.
- Sécurité améliorée : Puisque vous pouvez omettre des parties du JDK de votre build personnalisé, vous n’avez pas à vous soucier des vulnérabilités découvertes dans une partie que vous n’utilisez pas.
- Performance améliorée : Un autre avantage d’un package Java plus petit est un temps de démarrage amélioré et une exigence de mémoire plus faible.
- Application de l’unicité des packages : Puisque les modules spécifient les packages exposés, Java peut s’assurer que chaque package ne provient que d’un seul module et éviter la confusion sur ce qui est exécuté.