模块路径上是否有2个模块具有完全相同的名称(但内容略有不同)?
据我所知,Java 9编译器并没有抱怨它。我有2个模块声明如下:
module com.dj.helper {
exports com.dj.helper;
}
两者都包含com.dj.helper
包,但在包中内容不同。然后在我的主应用程序中,我想要导入这个模块:
module com.dj {
requires com.dj.helper;
}
具有相同名称的两个模块都在我的模块路径上。
我希望在编译我的com.dj
模块时,编译器会抱怨同一模块存在两次,但事实并非如此。这是否有效地意味着您可以在模块路径上拥有相同jar的2个版本,Java将不知道使用哪个版本?
答案 0 :(得分:6)
模块路径上的同一目录中不可能有两个同名的模块。官方文档并没有将这些信息放在一个特别突出的位置 - 它是the Javadoc of ModuleFinder::of
给出它的信息:
如果目录包含多个具有相同名称的模块,则会出错。
我通过创建同一模块的两个版本来创建a small demo project for the module system和it covers that case ...
jar --create
--file mods/monitor.observer.beta-1.0.jar
--module-version 1.0
-C classes/monitor.observer.beta .
jar --create
--file mods/monitor.observer.beta-2.0.jar
--module-version 2.0
-C classes/monitor.observer.beta .
...然后在下一个编译中引用该文件夹...
javac
--module-path mods
-d classes/monitor.statistics
$(find monitor.statistics -name '*.java')
...正如预期的那样导致以下错误消息:
error: duplicate module on application module path
module in monitor.observer.beta
1 error
请注意,我在同一目录中说 。在目录中可以有多个模块。
模块系统仅在目录中强制执行唯一性。再次来自ModuleFinder::of
(强调我的):
模块查找器通过按数组索引顺序搜索每个目录,爆炸模块或打包模块来查找模块。它找到第一次出现具有给定名称的模块,忽略该序列中稍后出现的其他模块。
这样就可以在不同的目录中拥有相同的模块。
答案 1 :(得分:5)
JEP 261描述模块路径如下:
模块路径是一个序列,其中每个元素都是模块定义或包含模块定义的目录。每个模块定义都是
模块工件,即模块化JAR文件或包含已编译模块定义的JMOD文件,否则
爆炸模块目录,按照惯例,其名称是模块的名称,其内容是与包层次结构对应的“展开”目录树。
然后介绍模块解析机制:
在模块路径中搜索特定名称的模块时,模块系统将获取该名称模块的第一个定义。版本字符串(如果存在)将被忽略; 如果模块路径的元素包含具有相同名称的多个模块的定义,则解析失败,编译器,链接器或虚拟机将报告错误并退出。构建工具和容器应用程序配置模块路径以避免版本冲突;模块系统的目标不是解决版本选择问题。
如上所述,这意味着只有在同一目录中存在两个具有相同名称的模块时,编译器才会抱怨。