En aras del argumento, afirmemos que Java 8 (y versiones anteriores) ya tiene una "forma" de módulos (jar) y un sistema de módulos (la ruta de clases). Pero existen problemas bien conocidos con estos.
Al examinar los problemas, podemos ilustrar la motivación de Jigsaw. (Lo siguiente supone que no estamos utilizando OSGi, módulos JBoss, etc., que ciertamente ofrecen soluciones).
Problema 1: el público también 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 usarUserDaoImpl
directamente. Sin embargo, no hay forma de hacer cumplir eso en la ruta de clases.
En Jigsaw, un módulo contiene un module-info.java
archivo que nos permite indicar explícitamente qué es público para otros módulos. Es decir, el público tiene matices. Por ejemplo:
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 aún 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, puede usarse para llegar a lo interno de un módulo de formas indeseables. Mark Reinhold tiene un ejemplo bastante alarmante . (La publicación SO está aquí ).
En Jigsaw, encapsulado 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, pendiente de la especificación técnica revisada para JDK 9.) Tenga en cuenta que debido a que Jigsaw se usa para el propio JDK, Oracle afirma que esto permitirá al equipo de Java innovar las partes internas de la plataforma más rápidamente.
Problema 3: la ruta de clases borra las relaciones arquitectónicas
Un equipo suele tener un modelo mental sobre las relaciones entre los frascos. Por ejemplo, foo-app.jar
puede usar foo-services.jar
which uses foo-db.jar
. Podríamos afirmar que las clases en foo-app.jar
no deben pasar por alto "la capa de servicio" y utilizarlas foo-db.jar
directamente. Sin embargo, no hay forma de hacer cumplir eso a través del classpath. Mark Reinhold menciona esto aquí .
En comparación, Jigsaw ofrece un modelo de accesibilidad explícito y confiable para módulos.
Problema 4: tiempo de ejecución monolítico
El tiempo de ejecución de Java es monolítico rt.jar
. En mi máquina, son más de 60 MB con 20k clases. En una era de microservicios, 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 propio JDK en muchos módulos; por ejemplo, java.sql contiene las conocidas clases SQL. Esto tiene varios beneficios, pero uno nuevo es la jlink
herramienta. Suponiendo que una aplicación está completamente modularizada, jlink
genera una imagen en tiempo de ejecución distribuible que se recorta para contener solo los módulos especificados (y sus dependencias). De cara al futuro, Oracle prevé un futuro en el que los módulos JDK se compilan con anticipación 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 el classpath no nos permite usar 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 expone la razón fundamental 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) sí abordan este problema (y otros, además de la # 4).
Línea de fondo
Éstos son algunos de los 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 separada que pertenece a otro sitio de Stack Exchange. Hay muchas más diferencias entre las soluciones que las que se describen aquí. Además, hubo suficiente consenso para aprobar la Boleta de reconsideración de revisión pública para JSR 376.