13

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

4

2 回答 2

9

在模块路径的同一目录中不可能有两个同名的模块。官方文档并没有将这些信息放在特别突出的位置 - 它是JavadocModuleFinder::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(强调我的):

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

这使得在不同的目录中有相同的模块成为可能。

于 2017-10-04T21:08:13.560 回答
5

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

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

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

  • 一个展开的模块目录,按照约定,其名称是模块的名称,其内容是对应于包层次结构的“展开”目录树。

然后描述了模块解析机制:

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

如前所述,这意味着只有在同一个目录中存在两个同名模块时,编译器才会报错。

于 2017-10-04T20:40:38.553 回答