web-dev-qa-db-fra.com

Qu'est-ce qu'un module automatique?

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?

23
ZhekaKozlov

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.

Qu'est-ce qu'un module automatique?

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.

Nom

Dériver le nom est un processus en deux étapes:

  • si le JAR définit le Automatic-Module-Name en-tête dans son manifeste, il définit le nom du module
  • sinon, le nom du fichier JAR est utilisé pour déterminer le nom

La seconde approche est intrinsèquement instable, donc aucun module dépendant d'un tel module automatique ne devrait être publié. Maven le prévient.

A besoin

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:

  • Dès que le premier module automatique est résolu, les autres aussi. Cela signifie qu'une fois qu'un seul JAR ordinaire sur le chemin du module est référencé par un autre module, tous les JAR ordinaires sont chargés en tant que modules automatiques.
  • Modules automatiques impliquent la lisibilité sur tous les autres modules automatiques, ce qui signifie qu'un module lisant l'un d'eux, les lit tous.

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) .

Exportations/Ouverture

É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.

Plus

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).

Module approprié

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.

Qu'est-ce qu'un module automatique pour ?

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.

32
Nicolai

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).

4
Naman

(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.

2
M Anouti