问题描述
背景
在maven中,工件可以声明依赖
In maven, an artifact can declare a dependency with
<optional>true</optional>
这意味着不需要依赖关系,但如果存在则可以使用。
which means that the dependency is not required, but can be used if present.
似乎指定了模块只能读取它所需的模块。
The State of the Module System seems to specify that a module can only read modules it has required.
问题
- Java 9模块系统确实不支持可选的依赖项吗?
- 为什么不呢?
- Java 9的可选依赖项有哪些替代方案?模块系统提供?
使用案例
我有一个集成应用程序可能使用或不使用的各种库的框架。目前,该框架是一个单独的JAR,它反映了类路径以跳过缺少库的集成代码。
I have a framework that integrates various libraries that may or may not be used by an application. Currently, this framework is a single JAR that reflects upon the classpath to skip integration code for absent libraries.
我想我们可以将它分成每个配置的单独模块,但这会导致JAR数量的组合爆炸,因为我们不仅需要一个为每个可选依赖项分离JAR,但对于大多数可选依赖项对,也是单独的JAR ...
I guess we could split this into a separate module for each configuration, but this would cause a combinatorial explosion in the number of JARs, because we'd not only need a separate JAR for each optional dependency, but also a separate JAR for most pairs of optional dependencies ...
推荐答案
是,。引自:
-
编译时,
需要静态M
表示强制依赖。如果在可观察模块中找不到合适的模块并进行解决,则会出错。
At compile time,
requires static M
expresses a mandatory dependence. It is an error if a suitable module cannot be found amongst the observable modules and resolved.
编译后的阶段,需要静态M
表示可选的依赖性。在解析期间,模块系统不会在可观察模块中搜索合适的模块,但如果生成的模块图包含合适的模块,那么它将在执行通常的解析后健全性检查之前添加适当的可读性边缘。 [...]
In phases after compile time, requires static M
expresses an optional dependence. The module system will not search the observable modules for a suitable module during resolution, but if the resulting module graph contains a suitable module then it will add the appropriate readability edge prior to doing the usual post-resolution sanity checks. [...]
因此,形式的假设模块声明
Thus a hypothetical module declaration of the form
module joda.beans {
requires static joda.collect;
...
}
将确保 joda.collect
模块在编译时可用,因此 joda.beans
模块中的代码引用 joda .collect
可以毫不费力地编译。但是,它不能保证 joda.collect
在链接时或运行时可用。
would ensure that the joda.collect
module is available at compile time, so that code in the joda.beans
module that refers to joda.collect
can be compiled without any fuss. It would not, however, guarantee that joda.collect
is available at link time or run time.
(与此同时,。)
我写了。有趣的花絮是声明可选依赖项的模块的 module-info.java
...
I wrote a demo for this. The interesting tidbits are the module-info.java
of the module declaring the optional dependencies...
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
类型不存在,它必须写入以便它不会失败:
... and the code within the same module that wants to access types from its optional dependencies. It has to written so that it fails graciously if the types ChocolateFactory
and/or QuoteFactory
are absent:
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();
}
}
最后,命令行可用于定义哪个应用程序启动的模块:
Finally, the command line can be used to define which modules the app launches with:
$java \
--add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \
-p mods -m org.codefx.demo.advent
当然,其他模块也可能非可选地要求它们,这迫使JVM将它们包含在模块图中。
It is of course also possible that other modules require them non-optionally, which forces the JVM to include them into the module graph.
这篇关于Java 9 Module系统是否支持可选的依赖项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!