Java 9:模块路径上可能有2个具有相同名称的模块

是否可以在模块路径上拥有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将不知道使用哪个版本?

模块系统的JEP 261描述模块路径如下:

模块路径是一个序列,其每个元素是模块定义或包含模块定义的目录。 每个模块定义都是

  • 模块工件 ,即模块化JAR文件或包含已编译模块定义的JMOD文件,否则

  • 一个分解模块目录 ,按照惯例,其名称是模块的名称,其内容是与包层次结构对应的“展开”目录树。

然后介绍模块解析机制:

在模块路径中搜索特定名称的模块时,模块系统将获取该名称的模块的第一个定义。 版本字符串(如果存在)将被忽略; 如果模块路径的元素包含具有相同名称的多个模块的定义,则解析将失败,编译器,链接器或虚拟机将报告错误并退出。 构建工具和容器应用程序负责配置模块路径以避免版本冲突; 模块系统的目标不是解决版本选择问题。

如上所述,这意味着只有当同一目录中存在两个具有相同名称的模块时,编译器才会抱怨。

没有

模块路径上的同一目录中不可能有两个同名的模块。 官方文档并没有将这些信息放在一个特别突出的位置 – 它是ModuleFinder::of的Javadoc ModuleFinder::of它给了它:

如果目录包含多个具有相同名称的模块,则会出错。

我已经为模块系统创建了一个小型演示项目 , 它通过创建同一模块的两个版本来涵盖这种情况 ……

 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 :(强调我的):

模块查找器通过以数组索引顺序搜索每个目录,爆炸模块或打包模块来查找模块。 它找到第一次出现具有给定名称的模块,并忽略序列中稍后出现的该名称的其他模块

这使得可以在不同的目录中具有相同的模块。