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

时间:2017-10-04 20:24:58

标签: java java-9 java-module module-info

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

2 个答案:

答案 0 :(得分:6)

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

  

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

我通过创建同一模块的两个版本来创建a small demo project for the module systemit 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文件,否则

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

  •   

然后介绍模块解析机制:

  

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

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