Les modules automatiques sont mentionnés plusieurs fois sur stackoverflow mais je n'ai pas pu trouver une définition complète, succincte et autosuffisante d'un module automatique.
Alors, qu'est-ce qu'un module automatique? Exporte-t-il tous les packages? Ouvre-t-il tous les packages? Lit-il tous les autres modules?
Je réponds d'abord à votre question réelle ("Qu'est-ce qu'un module automatique?"), Mais j'explique également à quoi ils servent pour . Il est difficile de comprendre pourquoi les modules automatiques se comportent comme ils le font sans ces informations.
Le système de modules crée un module à partir de chaque JAR qu'il trouve sur le chemin du module. Pour les fichiers JAR modulaires (c'est-à-dire ceux avec des descripteurs de module), c'est simple car ils définissent les propriétés du module (nom, exigences, exportations) . Pour les fichiers JAR simples (pas de descripteur de module), cette approche ne fonctionne pas, alors que devrait faire le système de modules à la place? Il crée automatiquement un module - un module automatique , pour ainsi dire - et prend les suppositions les plus sûres pour les trois propriétés.
Dériver le nom est un processus en deux étapes:
Automatic-Module-Name
en-tête dans son manifeste, il définit le nom du moduleLa seconde approche est intrinsèquement instable, donc aucun module dépendant d'un tel module automatique ne devrait être publié. Maven le prévient.
Puisqu'un JAR simple n'exprime aucune clause require, le système de modules permet aux modules automatiques de lire tous les autres modules qui en font graphique de lisibilité (aka module graphique). Contrairement aux modules explicites, les modules automatiques lisent également le module sans nom, qui contient tout ce qui a été chargé à partir du chemin de classe. Ce détail apparemment mineur s'avère très important (voir ci-dessous).
Les modules automatiques ont cependant quelques bizarreries de lisibilité supplémentaires:
Dans l'ensemble, cela peut avoir pour effet malheureux qu'un module explicite (c'est-à-dire non automatique) qui dépend de plusieurs fichiers JAR simples puisse s'en tirer sans nécessiter l'un d'eux (tant que les autres se retrouvent également sur le chemin du module) .
Étant donné que le JAR ne contient aucune information sur les packages considérés comme des API publiques et ceux qui ne le sont pas, le système de modules exporte tous les packages et les ouvre également pour une réflexion approfondie.
Le système de modules analyse également META-INF/services
et oblige le module automatique à fournir les services qui y sont nommés. Un module automatique est supposé autorisé à utiliser tous les services.
Finalement, le Main-Class
l'entrée de manifeste est également traitée, donc un simple JAR qui en définit un peut être lancé comme un module automatique où la classe principale a été définie avec l'outil jar
(c'est-à-dire Java --module-path my-app.jar --module my.app
).
Une fois le module automatique créé, il est traité comme tout autre module. Cela inclut explicitement que le système de modules le vérifie sur tout autre module, par exemple pour les packages fractionnés.
L'une des raisons de l'introduction de modules était de rendre la compilation et le lancement d'applications plus fiables et de trouver plus tôt les erreurs possibles avec le chemin de classe. Les clauses requires
en sont un aspect critique.
Pour les garder fiables, il n'y a aucun moyen pour une déclaration de module d'exiger autre chose qu'un module nommé, ce qui exclut tout ce qui est chargé du chemin de classe. Si l'histoire se terminait ici, un JAR modulaire ne pourrait dépendre que d'autres JAR modulaires, ce qui forcerait l'écosystème à se modulariser de bas en haut.
C'est inacceptable, cependant, donc les modules automatiques ont été introduits comme moyen pour les JAR modulaires de dépendre des JAR non modulaires et tout ce que vous devez faire pour cela est de placer le JAR ordinaire sur le chemin du module et de l'exiger par le nom du système de modules le donne.
Le bit intéressant est que parce que les modules automatiques lisent le module sans nom, il est possible (et je recommande généralement de le faire) de laisser ses dépendances sur le chemin de classe. De cette façon, les modules automatiques agissent comme un pont entre le module et le chemin de classe.
Vos modules peuvent s'asseoir d'un côté, nécessiter leurs dépendances directes en tant que modules automatiques, et les dépendances indirectes peuvent rester de l'autre côté. Chaque fois qu'une de vos dépendances se transforme en module explicite, elle quitte le pont du côté modulaire et dessine ses dépendances directes en tant que modules automatiques sur le pont.
Un module automatique est un module nommé qui est défini implicitement, car il n'a pas de déclaration de module . Un module nommé ordinaire, en revanche, est défini explicitement, avec une déclaration de module; nous les désignerons désormais comme modules explicites.
Le principal avantage de leur utilisation est qu'ils vous permettent de traiter un artefact comme un module lors de la compilation ou de l'exécution sans attendre sa migration vers la structure modulaire.
Le nom de module d'un module automatique est dérivé du fichier JAR utilisé pour inclure l'artefact s'il a l'attribut Automatic-Module-Name dans son manifeste principal entrée. Le nom du module est autrement dérivé du nom du fichier JAR par ModuleFinder
.
Dérivé du fait que le module automatique n'a pas de déclaration de module, il n'est pratiquement pas possible de dire ce que tous les modules ou packages lisent, ouvrent ou exportent.
➜ Donc, puisqu'il n'y a pas d'export/ouverture explicite pour les packages résidant dans le module automatique, décrit comme -
.. aucun moyen pratique de dire lesquels des packages d'un module automatique sont destinés à être utilisés par d'autres modules ou par des classes encore sur le chemin de classe. Chaque paquet d'un module automatique est donc considéré comme exporté même s'il ne peut en fait être destiné qu'à un usage interne.
➜ Citant le lien plus loin -
... aucun moyen pratique de savoir à l'avance de quels autres modules un module automatique pourrait dépendre. Par conséquent, une fois qu'un graphique de module est résolu, un module automatique est créé pour lire tous les autres modules nommés, qu'ils soient automatiques ou explicites.
Celui des propositions - Un module automatique offre le niveau traditionnel d'encapsulation: Tous les packages sont tous les deux ouverts pour un accès en réflexion profonde et exportés pour un accès ordinaire à la compilation et à l'exécution à leurs types publics.
➜ De plus, un module automatique
accorde lisibilité implicite à tous les autres modules automatiques
pour la raison que, tout en utilisant plusieurs modules automatiques dans un module, son
... impossible de déterminer si l'un des packages exportés dans un module automatique (x.y.z) contient un type dont la signature fait référence à un type défini dans un autre module automatique (a.b.c).
(Vous semblez avoir raison sur une définition complète manquante car je ne l'ai pas trouvée dans la langue ou les spécifications JVM)
Les Javadocs fournissent beaucoup de définitions formelles bien que dans le Java.lang.module
classes de packages.
Citation partielle de https://docs.Oracle.com/javase/9/docs/api/Java/lang/module/ModuleFinder.html#automatic-modules :
Un fichier JAR qui n'a pas de
module-info.class
dans son répertoire de niveau supérieur définit un module automatique , comme suit:
- Si le fichier JAR a l'attribut "
Automatic-Module-Name
"dans son manifeste principal, sa valeur est le nom du module. Le nom du module est autrement dérivé du nom du fichier JAR....
Et depuis https://docs.Oracle.com/javase/9/docs/api/Java/lang/module/ModuleDescriptor.html :
Le descripteur de module d'un module automatique ne déclare aucune dépendance (à l'exception de la dépendance obligatoire sur
Java.base
), et ne déclare aucun package exporté ou ouvert. Le module automatique reçoit un traitement spécial pendant la résolution afin de lire tous les autres modules de la configuration. Lorsqu'un module automatique est instancié dans la machine virtuelle Java, il lit tous les modules sans nom et est traité comme si tous les packages étaient exportés et ouverts.