背景
在maven中,工件可以声明依赖关系
<optional>true</optional>
Run Code Online (Sandbox Code Playgroud)
这意味着不需要依赖,但如果存在则可以使用.
模块系统的状态似乎指定模块只能读取它所需的模块.
问题
用例
我有一个框架,集成了应用程序可能使用或不使用的各种库.目前,该框架是一个单独的JAR,它反映了类路径以跳过缺少库的集成代码.
我想我们可以将它分成每个配置的单独模块,但这会导致JAR数量的组合爆炸,因为我们不仅需要为每个可选依赖项单独的JAR,而且对于大多数对都需要单独的JAR可选的依赖项......
我有一个简单的Java 9 SE项目,其中一个依赖于非模块化项目(在本例中选择了Weld SE),我正在尝试使用Maven(clean install)构建它.为了使Java 9能够启动,我已经添加了module-info.java.最初,此文件仅包含模块名称,并且没有requires公式.
请记住,我唯一的依赖是不是一个模块化的项目,因此,我认为Maven会放在类路径中(不模块路径),因此它会在结束unnamed module中描述的模块化系统的状态.
现在,我的Maven版本是3.3.9,我知道我需要在版本3.6中使用Maven编译器插件,如此处所述当然我已经使用jigsaw下载了JDK 9 EA build并设置了Maven来使用它.
如果我没有构建我的项目module-info.java,一切正常,将东西添加到类路径并构建成功.我想只要你遗漏那个文件,Maven就会坚持旧的方式.
但是,建造它有 module-info.java告诉我,从我的依赖的类不能在类路径中找到.所以我在调试模式下运行Maven(使用-X),确实 - 所有jar都在module-path下,classpath为空.这实际上意味着我的所有依赖项都被转移到自动模块中,我需要声明它们module-info.java.
一旦我声明了自动模块要求(链接到项目的module-info),我就可以在JDK 9上构建它.但它有点混乱 - 我唯一的pom.xml依赖是weld-se-core,但我module-info要求我宣布更多的编译要求通过.
这是一个完整的GitHub项目,可以观察到所有这些.
所以我的问题是:
automatic module并且需要声明它们?automatic module,我可以告诉Maven以某种方式过渡性地允许我的依赖需要引入的任何东西吗?例如Weld的其他部分,CDI API等.requires模块,我不直接使用?例如weld.environment.common我开始学习 jigsaw java-9 功能并阅读了一些文章/视频。
我无法理解可选依赖项的概念(requires static)
引自文章:
当一个模块需要针对另一个模块的类型进行编译但不想在运行时依赖它时,它可以使用 requires static 子句。如果 foo 需要 static bar,则模块系统在编译和运行时的行为会有所不同:
在编译时, bar 必须存在,否则会出错。在编译期间 bar 可由 foo 读取。
在运行时, bar 可能不存在,这不会导致错误或警告。如果它存在,它可以被 foo 读取。
所以我想知道几件事:
在编译时使模块依赖于另一个模块而不是运行时的原因是什么?任何例子?像龙目岛这样的乐器?
java之前的java-9中可选依赖项的任何类似物?
我找到了另一种解释:引自文章:
有时我们编写引用另一个模块的代码,但我们库的用户永远不想使用。
例如,我们可能会编写一个实用程序函数,当另一个日志模块存在时,它可以漂亮地打印我们的内部状态。但是,并非我们库的每个使用者都需要此功能,并且他们不想包含额外的日志记录库。
在这些情况下,我们希望使用可选的依赖项。通过使用 requires 静态指令,我们创建了一个仅编译时依赖:
module my.module {
requires static module.name;
}
Run Code Online (Sandbox Code Playgroud)
但对我来说完全不清楚。谁能用简单的方式解释一下?
我已经了解到,为了使用任何其他导出的模块,我们需要将该模块指定为requires:
module mymodule{
requires othermodule.xyz;
}
Run Code Online (Sandbox Code Playgroud)
当othermodule使用thirdmodule 和mymodule需要时, othermodule应该像这样定义传递依赖:
module othermodule {
requires transitive thirdmodule
}
Run Code Online (Sandbox Code Playgroud)
但是,我见过许多使用该public关键字的网站:
module othermodule {
requires public thirdmodule
}
Run Code Online (Sandbox Code Playgroud)
两种形式之间有什么区别; 即requires public和requires transitive?