2016-10-06 27 views
20

背景Java 9模块系统是否支持可选的依赖关系?

在行家中,工件可以声明的依赖性与

<optional>true</optional> 

这意味着不需要的依赖性,但如果存在的话可以使用。

The State of the Module System似乎指定模块只能读取它所需的模块。

问题

  • 是否在Java 9模块系统确实不支持可选的依赖?
  • 为什么不呢?
  • Java 9模块系统提供了哪些可选的依赖关系?

使用案例

我有一个框架,将可能会或可能不会被应用程序所使用的各种库。目前,这个框架是一个反映类路径跳过缺少库的集成代码的单个JAR。

我想我们可以将它分解为每个配置的单独模块,但是这会导致JAR数量的组合式爆炸,因为我们不仅需要为每个可选的依赖需要单独的JAR,而且还需要单独的JAR用于大多数可选依赖关系对...

回答

16

是,optional dependencies are supported。从the original proposal报价:

扩展模块声明的语言,以允许在requires指令使用的static改性剂,具有以下含义:

  • 在编译时,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不存在:

​​

最后,该命令行可用于定义哪些模块应用程序与启动:

$java \ 
    --add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \ 
    -p mods -m org.codefx.demo.advent 

当然也有可能其他模块要求它们是非必选的,这迫使JVM将它们包含到模块图中。

+1

供将来参考:您是否知道可选依赖项提案是否实际进入最终版本? – Lii

+2

目前还没有最终版本(Java 9计划于2017年7月发布),但它仍然是EA构建的一部分,并有可能被零边界所取代。 – Nicolai