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 derequires
, 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ódulojoda.beans
que hace referencia ajoda.collect
pueda compilarse sin ningún problema. Sin embargo, no garantizaría quejoda.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.