tutorial modules java java-9 jigsaw

java - modules - ¿Por qué proyecto Jigsaw/JPMS?



java 9 modules tutorial (5)

AFAIK El plan es hacer que el JRE sea más modular. Es decir, tiene frascos más pequeños que son opcionales y / o puede descargar / actualizar solo la funcionalidad que necesita.

Es para hacerlo menos hinchado y le da la opción de descartar módulos heredados que quizás la mayoría de la gente no usa.

El sistema de administración de paquetes de Java siempre me pareció simple y efectivo. Es muy utilizado por el propio JDK. Lo hemos estado usando para imitar el concepto de espacios de nombres y módulos.

¿Qué está tratando de completar Project Jigsaw (también conocido como Sistema de Módulo de Plataforma Java )?

Desde el sitio oficial:

El objetivo de este proyecto es diseñar e implementar un sistema de módulos estándar para la plataforma Java SE, y aplicar ese sistema a la plataforma misma y al JDK.


Basado en el discurso principal de Mark Reinhold en Devoxx Belgium , Project Jigsaw abordará dos puntos principales de dolor:

  1. Classpath
  2. Massive Monolithic JDK

¿Qué pasa con Classpath?

Todos sabemos sobre el Infierno JAR . Este término describe todas las formas en que el proceso de carga de clases puede terminar sin funcionar. Las limitaciones más conocidas de classpath son:

  • Es difícil saber si hay conflictos. Las herramientas de compilación como maven pueden hacer un buen trabajo basado en nombres de artefactos, pero si los artefactos tienen los mismos nombres pero los mismos contenidos, podría haber un conflicto.
  • El problema fundamental con los archivos jar es que no son componentes. Son solo un montón de contenedores de archivos que se buscarán linealmente. Classpath es una forma de buscar clases sin importar en qué componentes están, en qué paquetes están o en qué uso están destinados.

Massive Monolithic JDK

La gran naturaleza monolítica de JDK causa varios problemas:

  • No cabe en dispositivos pequeños. Aunque los dispositivos pequeños de tipo IoT tienen procesadores capaces de ejecutar una VM de clase SE, pero no necesariamente tienen la memoria para contener todo el JDK, especialmente cuando la aplicación solo usa una pequeña parte de ella.
  • Incluso es un problema en la nube. Cloud se trata de optimizar el uso del hardware, si tienes miles de imágenes que contienen todo el JDK pero las aplicaciones solo usan una pequeña parte, sería un desperdicio.

Módulos: la solución común

Para abordar los problemas anteriores, tratamos los módulos como un nuevo tipo fundamental de componente de programa Java. Un módulo es una recopilación de códigos y datos con nombre y autodescripción. Su código está organizado como un conjunto de paquetes que contienen tipos, es decir, clases e interfaces de Java; sus datos incluyen recursos y otros tipos de información estática.

Para controlar cómo su código se refiere a los tipos en otros módulos, un módulo declara qué otros módulos requiere para compilarse y ejecutarse. Para controlar cómo el código en otros módulos se refiere a los tipos en sus paquetes, un módulo declara cuál de esos paquetes exporta.

El sistema de módulos localiza los módulos requeridos y, a diferencia del mecanismo de ruta de clases, asegura que el código en un módulo solo puede referirse a los tipos en los módulos de los que depende. Los mecanismos de control de acceso del lenguaje Java y la máquina virtual Java impiden que el código acceda a los tipos en paquetes que no son exportados por sus módulos definidores.

Además de ser más confiable, la modularidad podría mejorar el rendimiento. Cuando el código en un módulo se refiere a un tipo en un paquete, se garantiza que dicho paquete se definirá en ese módulo o en uno de los módulos leídos por ese módulo. Al buscar la definición de un tipo específico, por lo tanto, no hay necesidad de buscarlo en múltiples módulos o, lo que es peor, a lo largo de toda la ruta de clase.

PECs a seguir

Jigsaw es un proyecto enorme que está en marcha desde hace unos años. Tiene una cantidad impresionante de JEP, que son excelentes lugares para obtener más información sobre el proyecto. Algunos de estos PEC son los siguientes:

  • JEP 200: El JDK modular : utilice el sistema de módulo de plataforma Java (JPMS) para modularizar el JDK
  • JEP 201: Código fuente modular : Reorganice el código fuente JDK en módulos, mejore el sistema de compilación para compilar módulos y haga cumplir los límites del módulo en tiempo de compilación.
  • JEP 261: Sistema de módulos : Implemente el Sistema de módulos de plataforma Java, según lo especificado por JSR 376, junto con los cambios y mejoras específicos relacionados con JDK.
  • JEP 220: Imágenes modulares en tiempo de ejecución : Reestructurar las imágenes JDK y JRE en tiempo de ejecución para acomodar módulos y mejorar el rendimiento, la seguridad y la capacidad de mantenimiento.
  • JEP 260: Encapsule la mayoría de las API internas : haga que la mayoría de las API internas del JDK sean inaccesibles por defecto, pero deje accesibles algunas API internas ampliamente utilizadas hasta que existan reemplazos compatibles para todas o la mayoría de sus funcionalidades.
  • JEP 282: jlink: El enlazador de Java: crea una herramienta que puede ensamblar y optimizar un conjunto de módulos y sus dependencias en una imagen personalizada en tiempo de ejecución como se define en JEP 220

Palabras de clausura

En la edición inicial del informe El Estado del Sistema de Módulos , Mark Reinhold describe los objetivos específicos del sistema de módulos de la siguiente manera:

  • Configuración confiable , para reemplazar el mecanismo de ruta de clase frágil y propenso a errores con un medio para que los componentes del programa declaren dependencias explícitas entre sí, junto con
  • Encapsulación fuerte , para permitir que un componente declare cuáles de sus tipos públicos son accesibles para otros componentes, y cuáles no.

Estas características beneficiarán a los desarrolladores de aplicaciones, desarrolladores de bibliotecas e implementadores de la plataforma Java SE directamente y, también, indirectamente, ya que permitirán una plataforma escalable, una mayor integridad de la plataforma y un mejor rendimiento.


En aras de la argumentación, afirmemos que Java 8 (y anterior) ya tiene una "forma" de módulos (jarras) y un sistema de módulos (la ruta de clases). Pero hay problemas bien conocidos con estos.

Al examinar los problemas, podemos ilustrar la motivación para Jigsaw. (Lo siguiente asume que no estamos usando OSGi, JBoss Modules, etc., que ciertamente ofrecen soluciones).

Problema 1: el público es demasiado público

Considere las siguientes clases (suponga que ambas son públicas):

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

En Foo.com, podríamos decidir que nuestro equipo debería usar UserDao y no usar UserDaoImpl directamente. Sin embargo, no hay forma de aplicar eso en el classpath.

En Jigsaw, un módulo contiene un archivo module-info.java que nos permite indicar explícitamente qué es público para otros módulos. Es decir, el público tiene matices. Por ejemplo:

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

Problema 2: la reflexión es desenfrenada

Dadas las clases en el n. ° 1, alguien podría hacer esto en Java 8:

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

Es decir: la reflexión es poderosa y esencial, pero si no se controla, se puede usar para alcanzar las partes internas de un módulo de formas no deseadas. Mark Reinhold tiene un ejemplo bastante alarmante . (La publicación de SO está here ).

En Jigsaw, la encapsulación fuerte ofrece la capacidad de denegar el acceso a una clase, incluida la reflexión. (Esto puede depender de la configuración de la línea de comandos, a la espera de la especificación técnica revisada para JDK 9.) Tenga en cuenta que debido a que Jigsaw se usa para el JDK, Oracle afirma que esto permitirá que el equipo de Java innove los componentes internos de la plataforma más rápidamente.

Problema 3: el classpath borra las relaciones arquitectónicas

Un equipo generalmente tiene un modelo mental sobre las relaciones entre jarras. Por ejemplo, foo-app.jar puede usar foo-services.jar que usa foo-db.jar . Podríamos afirmar que las clases en foo-app.jar no deben omitir "la capa de servicio" y usar foo-db.jar directamente. Sin embargo, no hay forma de aplicar eso a través del classpath. Mark Reinhold lo menciona aquí .

En comparación, Jigsaw ofrece un modelo de accesibilidad explícito y confiable para los módulos.

Problema 4: tiempo de ejecución monolítico

El tiempo de ejecución de Java se encuentra en el rt.jar monolítico. ¡En mi máquina, es más de 60 MB con 20k clases! En una era de micro-servicios, dispositivos IoT, etc., no es deseable tener Corba, Swing, XML y otras bibliotecas en el disco si no se están utilizando.

Jigsaw divide el JDK en muchos módulos; por ejemplo, java.sql contiene las clases SQL familiares. Hay varios beneficios en esto, pero uno nuevo es la herramienta jlink . Suponiendo que una aplicación está completamente modularizada, jlink genera una imagen distribuible en tiempo de ejecución que se recorta para contener solo los módulos especificados (y sus dependencias). De cara al futuro, Oracle visualiza un futuro donde los módulos JDK se compilan anticipadamente en código nativo. Aunque jlink es opcional, y la compilación de AOT es experimental, son indicaciones importantes de hacia dónde se dirige Oracle.

Problema 5: control de versiones

Es bien sabido que classpath no nos permite utilizar múltiples versiones del mismo jar: por ejemplo, bar-lib-1.1.jar y bar-lib-2.2.jar .

Jigsaw no aborda este problema; Mark Reinhold establece el razonamiento aquí . La esencia es que Maven, Gradle y otras herramientas representan un gran ecosistema para la gestión de la dependencia, y otra solución será más dañina que beneficiosa.

Cabe señalar que otras soluciones (por ejemplo, OSGi) abordan este problema (y otras, aparte del n. ° 4).

Línea de fondo

Estos son algunos puntos clave para Jigsaw, motivados por problemas específicos.

Tenga en cuenta que explicar la controversia entre Jigsaw, OSGi, JBoss Modules, etc. es una discusión por separado que pertenece a otro sitio de Stack Exchange. Hay muchas más diferencias entre las soluciones que las aquí descritas. Además, hubo suficiente consenso para aprobar la Boleta de reconsideración de revisión pública para JSR 376.


Este artículo explica en detalle los problemas que tanto OSGi como JPMS / Jigsaw intentan resolver:

"Java 9, OSGi y el futuro de la modularidad" [22 SEP 2016]

También profundiza en los enfoques de OSGi y JPMS / Jigsaw. A partir de ahora, parece que los autores casi no enumeraron Pros prácticos para JPMS / Jigsaw en comparación con OSGi madurado (16 años).


Jigsaw y OSGi están tratando de resolver el mismo problema: cómo permitir que los módulos de grano grueso interactúen mientras protegen sus partes internas.

En el caso de Jigsaw, los módulos de grano más grueso incluyen clases Java, paquetes y sus dependencias.

Aquí hay un ejemplo: Spring e Hibernate. Ambos tienen una dependencia en un JAR CGLIB de terceros, pero usan versiones diferentes e incompatibles de ese JAR. ¿Qué puede hacer si confía en el estándar JDK? Incluyendo la versión que Spring quiere rompe Hibernate y viceversa.

Pero, si tiene un modelo de nivel superior como Jigsaw, puede administrar fácilmente diferentes versiones de un JAR en diferentes módulos. Piense en ellos como paquetes de mayor nivel.

Si construyes Spring desde la fuente GitHub, lo verás también. Han rediseñado el marco, por lo que consta de varios módulos: núcleo, persistencia, etc. Puede seleccionar y elegir el conjunto mínimo de dependencias de módulo que su aplicación necesita e ignorar el resto. Solía ​​ser un Spring JAR único, con todos los archivos .class en él.

Actualización: Cinco años después: Jigsaw aún podría tener algunos issues que resolver.