tutorial programacion modulos modules modularidad ejercicios como aplica java java-9 jigsaw

programacion - java 9 modules tutorial



¿El sistema Java 9 Module soporta dependencias opcionales? (1)

Fondo

En Maven, un artefacto puede declarar una dependencia con

<optional>true</optional>

lo que significa que la dependencia no es necesaria, pero se puede usar si está presente.

El estado del sistema de módulos parece especificar que un módulo solo puede leer los módulos que ha requerido.

Preguntas

  • ¿El sistema de módulos Java 9 no soporta dependencias opcionales?
  • Por qué no?
  • ¿Qué alternativas a las dependencias opcionales ofrece el sistema de módulos Java 9?

Caso de uso

Tengo un marco que integra varias bibliotecas que una aplicación puede o no usar. Actualmente, este marco es un JAR único que refleja la ruta de clase para omitir el código de integración para bibliotecas ausentes.

Supongo que podríamos dividir esto en un módulo separado para cada configuración, pero esto causaría una explosión combinatoria en el número de JARs, porque no solo necesitaríamos un JAR separado para cada dependencia opcional, sino también un JAR separado para la mayoría de los pares de dependencias opcionales ...


Sí, se admiten dependencias opcionales . Citando de la propuesta original :

Extienda el lenguaje de las declaraciones de los módulos para permitir que el modificador static se use en una directiva de requires , con los siguientes significados:

  • En el momento de la compilación, requires static M expresa una dependencia obligatoria. Es un error si un módulo adecuado no se encuentra entre los módulos observables y se resuelve.

  • En las fases posteriores al tiempo de compilación, requires static M expresa una dependencia opcional. El sistema de módulos no buscará en los módulos observables un módulo adecuado durante la resolución, pero si el gráfico del módulo resultante contiene un módulo adecuado, agregará el límite de legibilidad adecuado antes de realizar las comprobaciones de saneamiento habituales posteriores a la resolución. [...]

Así, un módulo hipotético de declaración de la forma.

module joda.beans { requires static joda.collect; ... }

aseguraría que el módulo joda.collect esté disponible en tiempo de compilación, de modo que el código en el módulo joda.beans que hace referencia a joda.collect pueda compilarse sin ningún problema. Sin embargo, no garantizaría que joda.collect esté disponible en el momento del enlace o en el tiempo de ejecución.

(Mientras tanto, se creó la documentación oficial para esa función ).

Escribí una demo para esto. Los module-info.java interesantes son el módulo- module-info.java del módulo que declara las dependencias opcionales ...

module org.codefx.demo.advent { // list the required modules requires org.codefx.demo.advent.calendar; // with ''static'' the factories are only required at compile time; // to be present at run time either other modules most require them // or they must be added with the ''--add-modules'' command line option requires static org.codefx.demo.advent.factory.chocolate; requires static org.codefx.demo.advent.factory.quote; }

... y el código dentro del mismo módulo que desea acceder a los tipos desde sus dependencias opcionales. Se debe escribir para que falle correctamente si los tipos ChocolateFactory y / o QuoteFactory están ausentes:

private static List<SurpriseFactory> createSurpriseFactories() { return Stream.of( createChocolateFactoryIfAccessible(), createQuoteFactoryIfAccessible()) .flatMap(Optional::stream) .collect(toList()); } private static Optional<SurpriseFactory> createChocolateFactoryIfAccessible() { try { return Optional.of(new ChocolateFactory()); } catch (NoClassDefFoundError er) { return Optional.empty(); } } private static Optional<SurpriseFactory> createQuoteFactoryIfAccessible() { try { return Optional.of(new QuoteFactory()); } catch (NoClassDefFoundError er) { return Optional.empty(); } }

Finalmente, la línea de comandos se puede usar para definir con qué módulos se lanza la aplicación:

$java / --add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote / -p mods -m org.codefx.demo.advent

Por supuesto, también es posible que otros módulos los requieran de forma no opcional, lo que obliga a la JVM a incluirlos en el gráfico del módulo.