Java 9 Module系统是否支持可选的依赖项? [英] Does the Java 9 Module system support optional dependencies?

查看:83
本文介绍了Java 9 Module系统是否支持可选的依赖项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

在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 ...

推荐答案

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


扩展模块声明的语言,以允许使用 static 修饰符a 需要指令,含义如下:

Extend the language of module declarations to allow the static modifier to be used on a requires directive, with the following meanings:


  • 编译时,需要静态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系统是否支持可选的依赖项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆