首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 9模块系统支持可选依赖关系吗?

Java 9模块系统支持可选依赖关系吗?
EN

Stack Overflow用户
提问于 2016-10-06 15:48:49
回答 1查看 2.1K关注 0票数 28

背景

在maven中,工件可以用

代码语言:javascript
复制
<optional>true</optional>

这意味着不需要依赖项,但如果存在则可以使用该依赖项。

模块系统的状态似乎指定一个模块只能读取它所需的模块。

问题

  • Java 9模块系统确实不支持可选依赖关系吗?
  • 为什么不行?
  • Java 9模块系统提供了哪些替代可选依赖项?

用例

我有一个框架,它集成了各种库,这些库可能被应用程序使用,也可能不会被应用程序使用。目前,这个框架是一个单独的JAR,它反映在类路径上,以跳过缺席库的集成代码。

我想我们可以为每个配置将其分成一个单独的模块,但是这将导致JAR数量的组合爆炸,因为我们不仅需要为每个可选依赖项单独创建一个JAR,而且对于大多数可选依赖项也需要一个单独的JAR.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-06 16:26:00

是的,支持可选依赖项。。引用原提案

扩展模块声明的语言,允许在static指令中使用requires修饰符,其含义如下:

  • 在编译时,requires static M表示强制依赖。如果在可观测模块中找不到合适的模块并加以解决,这将是一个错误。
  • 在编译后的各个阶段,requires static M表示一个可选的依赖关系。在解析过程中,模块系统不会搜索可观测模块寻找合适的模块,但是如果得到的模块图包含一个合适的模块,那么在进行通常的分辨率后检查之前,它将添加适当的可读性边缘。..。

因此,表单的假设模块声明

模块joda.beans {需要静态joda.collect;.}

将确保joda.collect模块在编译时可用,以便可以不费吹灰之力地编译引用joda.collectjoda.beans模块中的代码。但是,它不能保证joda.collect在链接时或运行时可用。

(同时,为此创建了正式文档。.)

我为此写了演示。有趣的消息是模块的module-info.java,它声明了可选的依赖项.

代码语言:javascript
复制
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类型,则必须编写这样的代码,这样才能很好地失败:

代码语言:javascript
复制
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();
    }
}

最后,可以使用命令行定义应用程序用以下方式启动的模块:

代码语言:javascript
复制
$java \
    --add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \
    -p mods -m org.codefx.demo.advent

当然,其他模块也可能非选择性地要求它们,这迫使JVM将它们包含到模块图中。

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39900460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档