背景
在maven中,工件可以使用
声明依赖关系<optional>true</optional>
表示不需要依赖项,但如果存在则可以使用。
onClose似乎指定模块只能读取它所需的模块。
问题
使用案例
我有一个框架,它集成了应用程序可能使用或不使用的各种库。目前,该框架是一个单独的JAR,它反映了类路径以跳过缺少库的集成代码。
我想我们可以将它分成每个配置的单独模块,但这会导致JAR数量的组合爆炸,因为我们不仅需要为每个可选依赖项单独使用JAR,而且还需要为大多数可选依赖项对分开JAR ......
答案 0 :(得分:19)
是的,optional dependencies are supported。引自the original proposal:
扩展模块声明的语言,以允许在
static
指令上使用requires
修饰符,具有以下含义:
在编译时,
requires static M
表示强制依赖。如果在可观察模块中找不到合适的模块并进行解决,则会出错。在编译时间之后的阶段,
requires static M
表示可选的依赖关系。在解析期间,模块系统不会在可观察模块中搜索合适的模块,但如果生成的模块图包含合适的模块,那么它将在执行通常的解析后完整性检查之前添加适当的可读性边缘。 [...]因此,形式
的假设模块声明module joda.beans { requires static joda.collect; ... }
将确保
joda.collect
模块在编译时可用,以便joda.beans
模块中引用joda.collect
的代码可以毫不费力地编译。但是,它不能保证joda.collect
在链接时或运行时可用。
(与此同时,official documentation was created for that feature。)
我为此写了a demo。有趣的花絮是模块的module-info.java
,声明可选的依赖...
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;
}
...以及想要从其可选依赖项访问类型的同一模块中的代码。它必须写入,以便在ChocolateFactory
和/或QuoteFactory
类型不存在的情况下失败:
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();
}
}
最后,命令行可用于定义应用程序启动的模块:
$java \
--add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \
-p mods -m org.codefx.demo.advent
当然,其他模块也可能非可选地要求它们,这迫使JVM将它们包含在模块图中。