¿Es necesario cambiar a módulos al migrar a Java 9 + / Java 11?

80

Actualmente estamos migrando de Java 8 a Java 11. Sin embargo, actualizar nuestros servicios fue menos doloroso de lo que anticipamos. Básicamente, solo tuvimos que cambiar el número de versión en nuestro build.gradlearchivo y los servicios estaban felices y funcionando. Actualizamos las bibliotecas y los (micro) servicios que utilizan esas bibliotecas. Sin problemas hasta ahora.

¿Existe alguna necesidad de cambiar a módulos? Esto generaría costos innecesarios en mi humilde opinión. Se agradece cualquier sugerencia o material de lectura adicional.

Para aclarar, ¿hay alguna consecuencia si se usa el código Java 9+ sin introducir módulos? ¿Puede, por ejemplo, volverse incompatible con otro código?

Younes EO
fuente
10
Es el mismo riesgo que ya enfrentó en Java 8: terminar en "Classpath Hell".
4
El resumen sotms / # respondería hasta cierto punto. Puede verificar si los objetivos de su proyecto están alineados con el proyecto Jigsaw . Aparte de eso, en mi opinión, es una cuestión de estar actualizado también lo que importa para las bibliotecas / servicios que brindan apoyo a sus consumidores.
Naman
4
@Taschi No creo que classpath hell por sí solo justifique volverse modular, ya que todo el código anterior a Java 9 tenía ese problema y, en la mayoría de los casos, hemos estado bien con él (personalmente nunca tuve un problema con él).
Younes EO
1
@Naman mencionar los objetivos del rompecabezas del proyecto es de hecho un muy buen argumento.
Younes EO
8
@Younes El Ouarti, eliminar "Classpath Hell" es uno de los dos objetivos declarados de Project Jigsaw. Si crees que no es una razón suficiente para tratar con Jigsaw, bueno ... Estoy de acuerdo contigo y evito a Jigsaw siempre que puedo.

Respuestas:

132

No.

No es necesario cambiar a módulos.

Nunca ha sido necesario cambiar a módulos.

Java 9 y las versiones posteriores admiten archivos JAR tradicionales en la ruta de clase tradicional, a través del concepto del módulo sin nombre, y probablemente lo harán hasta la muerte térmica del universo.

Si desea comenzar a usar módulos, depende completamente de usted.

Si mantiene un gran proyecto heredado que no cambia mucho, probablemente no valga la pena el esfuerzo.

Si trabaja en un proyecto grande que se ha vuelto difícil de mantener a lo largo de los años, la claridad y la disciplina que aporta la modularización podrían ser beneficiosas, pero también podría suponer mucho trabajo, así que piense detenidamente antes de comenzar.

Si está comenzando un nuevo proyecto, le recomiendo que comience con los módulos si puede. Muchas bibliotecas populares ya se han actualizado para que sean módulos , por lo que es muy probable que todas las dependencias que necesita ya estén disponibles en forma modular.

Si mantiene una biblioteca, le recomiendo encarecidamente que la actualice para que sea un módulo si aún no lo ha hecho y si todas las dependencias de su biblioteca se han convertido.

Todo esto no quiere decir que no encontrará algunos obstáculos al pasar de Java 8. Sin embargo, los que encuentre probablemente no tendrán nada que ver con los módulos en . Los problemas de migración más comunes de los que hemos escuchado desde que lanzamos Java 9 en 2017 tienen que ver con los cambios en la sintaxis de la cadena de la versión y con la eliminación o encapsulación de API internas ( por ejemplo , sun.misc.Base64Decoder) para las cuales se han implementado reemplazos públicos y compatibles. estado disponible durante años.

Mark Reinhold
fuente
26

Solo puedo decirles la opinión de mi organización al respecto. Nos encontramos en el proceso de mover a los módulos, para cada proyecto que estamos trabajando. Lo que estamos construyendo son básicamente microservicios + algunas bibliotecas cliente. Para los microservicios, la transición a moduleses de alguna manera una prioridad menor: el código ya está aislado de alguna manera en el contenedor de la ventana acoplable, por lo que "agregar" módulos allí no parece (para nosotros) muy importante. Este trabajo se está recuperando lentamente, pero es de baja prioridad.

Por otro lado, las bibliotecas cliente es una historia completamente diferente. No puedo decirte el lío que tenemos a veces. Explicaré un punto que odié antes jigsaw. Expone una interfaz a los clientes, para que todos la utilicen. Automáticamente eso interfacees public- expuesto al mundo. Por lo general, lo que hago es tener algunas package-privateclases, que no están expuestas a los clientes, que usan esa interfaz. No quiero que los clientes usen eso, es interno. ¿Suena bien? Incorrecto.

El primer problema es que cuando esas package-privateclases crecen y quieres más clases, la única forma de mantener todo oculto es crear clases en el mismo paquete:

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....

Cuando crece (en nuestros casos lo hace), esos paquetes son demasiado grandes. ¿Te mudas a un paquete separado que dices? Claro, pero eso HelperUsagey FactoryUsagelo será publicy tratamos de evitarlo desde el principio.

Problema número dos: cualquier usuario / llamador de nuestros clientes puede crear el mismo nombre de paquete y extender esas clases ocultas. Ya nos pasó algunas veces, momentos divertidos.

modulesresuelve este problema de una manera hermosa: publicya no es realmente public ; Puedo tener friendacceso vía exports todirectiva. Esto facilita mucho la gestión y el ciclo de vida de nuestro código. Y nos alejamos del infierno de classpath. Por supuesto, maven/gradlemaneje eso por nosotros, principalmente, pero cuando hay un problema, el dolor será muy real. También podría haber muchos otros ejemplos.

Dicho esto, la transición (todavía) no es fácil. En primer lugar, todos los miembros del equipo deben estar alineados; segundo, hay obstáculos. Los dos más importantes que todavía veo son: ¿cómo se separa cada módulo, en función de qué, específicamente? Todavía no tengo una respuesta definitiva. La segunda es split-packages, oh, lo hermoso "la misma clase es exportada por diferentes módulos". Si esto sucede con sus bibliotecas, hay formas de mitigarlo; pero si se trata de bibliotecas externas ... no es tan fácil.

Si depende de jarAy jarB(módulos separados), pero ambos exportan abc.def.Util, se encontrará con una sorpresa. Sin embargo, hay formas de resolver esto. De alguna manera doloroso, pero con solución.

En general, desde que migramos a módulos (y todavía lo hacemos), nuestro código se ha vuelto mucho más limpio. Y si su empresa es una empresa de "código primero", esto es importante. Por otro lado, he estado involucrado en empresas en las que los arquitectos senior consideraban que esto era "demasiado caro", "ningún beneficio real".

Eugenio
fuente
4
¡Gracias por los incites! Entonces, lo que obtengo es que la modularización viene con las restricciones de acceso tan necesarias que nos faltaban en versiones anteriores. Definitivamente puedo ver cómo esto es útil para las bibliotecas. En caso de que se comunique un servicio a través de REST / AMQP / etc. esto nuevamente no es un gran problema, o más bien, ¿no hay beneficios? ¿Quizás no podemos decir arbitrariamente que todo el código de Java 9+ debería ser modular? Entonces, ¿deberíamos considerarlo como una "herramienta" en sí misma? Interesante sin embargo.
Younes EO
Lo que podría encontrar útil es un patrón de API de "acceso" (pero tenga en cuenta que en lugar de un campo estático público, se prefiere uno privado con métodos, para evitar puntos muertos durante la carga de clases). Ver aquí: wiki.netbeans.org/…
Tomáš Myšík
¡Gracias por compartir su experiencia! Sería bueno que compartiera más detalles o enlaces a los problemas que mencionó que son dolorosos, pero que aún se pueden resolver.
botismarius
3
"Problema número dos: cualquier usuario / llamador de nuestros clientes puede crear el mismo nombre de paquete y extender esas clases ocultas". Mucho antes de Java 9, los paquetes se podían sellar para evitar esto. (Creo que los módulos son una excelente idea y los uso en todos mis proyectos. Solo quería señalar que este caso de uso en particular no los requiere).
VGR