java - ¿Qué es un módulo automático?
java-9 jigsaw (3)
Un módulo automático es un módulo con nombre que se define implícitamente, ya que no tiene una declaración de módulo . Un módulo con nombre ordinario, por el contrario, se define explícitamente, con una declaración de módulo; de ahora en adelante nos referiremos a ellos como módulos explícitos .
El beneficio principal de usar estos es que le permiten tratar un artefacto como un módulo al compilar o ejecutar sin esperar a que se migre a la estructura modular.
El nombre del módulo de un módulo automático se deriva del archivo JAR utilizado para incluir el artefacto si tiene el atributo
Automatic-Module-Name
en su entrada de manifiesto principal.
El nombre del módulo se deriva del nombre del archivo JAR por
ModuleFinder
.
Derivado del hecho de que el módulo automático no tiene una declaración de módulo, prácticamente no es factible decir qué todos los módulos o paquetes lee, abre o exporta.
➜ Entonces, dado que no hay exportaciones / aperturas explícitas para paquetes que residen en el módulo automático, descrito como -
.. no hay forma práctica de saber cuál de los paquetes en un módulo automático está destinado a ser utilizado por otros módulos, o por clases que todavía están en la ruta de clase. Por lo tanto, cada paquete en un módulo automático se considera exportado, incluso si en realidad podría estar destinado solo para uso interno.
➜ Citando el enlace más adelante -
... no hay forma práctica de saber, de antemano, de qué otros módulos puede depender un módulo automático. Después de resolver un gráfico de módulo, por lo tanto, se crea un módulo automático para leer todos los demás módulos con nombre, ya sea automático o explícito.
Una de las proposals : un módulo automático ofrece el nivel tradicional de encapsulación: todos los paquetes están abiertos para un acceso reflexivo profundo y se exportan para acceso ordinario en tiempo de compilación y tiempo de ejecución a sus tipos públicos .
➜ Además, un módulo automático
otorga legibilidad implícita a todos los demás módulos automáticos
debido a la razón, que al usar múltiples módulos automáticos en un módulo
..no es factible determinar si uno de los paquetes exportados en un módulo automático (xyz) contiene un tipo cuya firma se refiere a un tipo definido en algún otro módulo automático (abc).
Los módulos automáticos se mencionan muchas veces en stackoverflow, pero no pude encontrar una definición completa, sucinta y autosuficiente de un módulo automático.
Entonces, ¿qué es un módulo automático? ¿Exporta todos los paquetes? ¿Abre todos los paquetes? ¿Lee todos los demás módulos?
(Parece que tiene razón acerca de una definición completa que falta, ya que no la encontré en el lenguaje o las especificaciones de JVM)
Los Javadocs proporcionan una gran cantidad de definiciones formales, aunque en las clases de paquetes
java.lang.module
.
Cita parcial de https://docs.oracle.com/javase/9/docs/api/java/lang/module/ModuleFinder.html#automatic-modules :
Un archivo JAR que no tiene un
module-info.class
en su directorio de nivel superior define un módulo automático , de la siguiente manera:
- Si el archivo JAR tiene el atributo "
Automatic-Module-Name
" en su manifiesto principal, entonces su valor es el nombre del módulo. El nombre del módulo se deriva del nombre del archivo JAR....
Y de https://docs.oracle.com/javase/9/docs/api/java/lang/module/ModuleDescriptor.html :
El descriptor de módulo para un módulo automático no declara ninguna dependencia (excepto la dependencia obligatoria en
java.base
), y no declara ningún paquete exportado o abierto. El módulo automático recibe un tratamiento especial durante la resolución para que lean todos los demás módulos en la configuración. Cuando se crea una instancia de un módulo automático en la máquina virtual Java, lee todos los módulos sin nombre y se trata como si todos los paquetes se exportaran y se abrieran.
Primero respondo a su pregunta real ("¿Qué es un módulo automático?"), Pero también le explico para qué sirven. Es difícil entender por qué los módulos automáticos se comportan de esa manera sin esa información.
¿Qué es un módulo automático?
El sistema de módulos crea un módulo a partir de cada JAR que encuentra en la ruta del módulo. Para los JAR modulares (es decir, aquellos con descriptores de módulo) es sencillo ya que definen las propiedades del módulo (nombre, requisitos, exportaciones) . Para los JAR simples (sin descriptor de módulo) este enfoque no funciona, entonces, ¿qué debería hacer el sistema de módulos en su lugar? Crea automáticamente un módulo, un módulo automático , por así decirlo, y toma las conjeturas más seguras para las tres propiedades.
Nombre
Derivar el nombre es un proceso de dos pasos:
-
si el JAR define el encabezado
Automatic-Module-Name
en su manifiesto, define el nombre del módulo - de lo contrario, el nombre del archivo JAR se usa para determinar el nombre
El segundo enfoque es intrínsecamente inestable, por lo que no se deben publicar módulos que dependan de dicho módulo automático. Maven advierte sobre eso.
Requiere
Dado que un JAR simple no expresa cláusulas requeridas, el sistema de módulos permite que los módulos automáticos lean todos los demás módulos que se incluyen en el gráfico de legibilidad (también conocido como gráfico de módulo). A diferencia de los módulos explícitos, los automáticos también leen el módulo sin nombre, que contiene todo lo que se cargó desde la ruta de clase. Este detalle aparentemente menor resulta ser muy importante (ver más abajo).
Sin embargo, los módulos automáticos tienen algunas peculiaridades de legibilidad adicionales:
- Tan pronto como se resuelva el primer módulo automático, también lo estarán todos los demás. Eso significa que una vez que otro módulo hace referencia a un JAR simple en la ruta del módulo, todos los JAR simples se cargan como módulos automáticos.
- Los módulos automáticos implican legibilidad en todos los demás módulos automáticos, lo que significa que un módulo que lee uno de ellos, los lee a todos.
Tomados en conjunto, esto puede tener el desafortunado efecto de que un módulo explícito (es decir, uno no automático) que depende de varios JAR simples puede salirse con la necesidad de requerir solo uno de ellos (siempre que los otros terminen también en la ruta del módulo) .
Exportaciones / Abre
Dado que el JAR no contiene información sobre qué paquetes se consideran API públicas y cuáles no, el sistema de módulos exporta todos los paquetes y también los abre para una reflexión profunda.
Más
El sistema de módulos también escanea
META-INF/services
y hace que el módulo automático brinde los servicios nombrados allí.
Se supone que un módulo automático puede usar todos los servicios.
Finalmente, la entrada de manifiesto de
Main-Class
se procesa, por lo que un JAR simple que define uno se puede iniciar como un módulo automático donde la clase principal se configuró con la herramienta
jar
(es decir,
java --module-path my-app.jar --module my.app
).
Módulo adecuado
Una vez que se creó el módulo automático, se trata como cualquier otro módulo. Esto incluye explícitamente que el sistema de módulos lo verifica como cualquier otro módulo, por ejemplo, para paquetes divididos.
¿Para qué sirve un módulo automático?
Una de las razones para la introducción de módulos fue hacer que la compilación y el lanzamiento de aplicaciones sean más confiables y encontrar los errores más pronto posible con la ruta de clase.
Un aspecto crítico de eso
requires
cláusulas.
Para mantenerlos confiables, no hay forma de que una declaración de módulo requiera algo más que un módulo con nombre, lo que excluye todo lo cargado de la ruta de clase. Si la historia terminara aquí, un JAR modular solo podría depender de otros JAR modulares, lo que obligaría al ecosistema a modularizarse de abajo hacia arriba.
Sin embargo, eso es inaceptable, por lo que los módulos automáticos se introdujeron como un medio para que los JAR modulares dependan de los no modulares y todo lo que necesita hacer para eso es colocar el JAR simple en la ruta del módulo y requerirlo con el nombre del sistema de módulos. lo da
Lo interesante es que debido a que los módulos automáticos leen el módulo sin nombre, es factible (y generalmente recomiendo hacerlo) dejar sus dependencias en la ruta de clase. De esta forma, los módulos automáticos actúan como un puente desde el módulo a la ruta de clase.
Sus módulos pueden sentarse en un lado, requieren sus dependencias directas como módulos automáticos, y las dependencias indirectas pueden permanecer en el otro lado. Cada vez que una de sus dependencias se convierte en un módulo explícito, deja el puente en el lado modular y dibuja sus dependencias directas como módulos automáticos en el puente.