Java 9:模块路径上是否可能有两个同名模块?

12

在模块路径上是否可能拥有两个名称完全相同但内容略有不同的模块?

据我所知,Java 9编译器不会对此进行投诉。我有两个声明如下的模块:

module com.dj.helper {
    exports com.dj.helper;
}

两者都包含 com.dj.helper 包,但包内的内容不同。然后在我的主应用程序中,我希望导入这个模块:

module com.dj {
    requires com.dj.helper;
}

我的模块路径上有两个同名的模块。

编译我的com.dj模块时,我希望编译器会抱怨存在相同的模块,但实际上并没有。这是否意味着你可以在模块路径上拥有两个版本相同的JAR包,Java将不知道该使用哪一个?

2个回答

8

不行

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

如果一个目录包含两个同名的模块,则会报错。

我创建了一个小演示项目来展示模块系统它涵盖了这种情况,通过创建相同模块的两个版本...

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
你的 monitor.statistics 模块不应该依赖于 monitor.observer.beta 模块吗? - DJ180
@manouti 哦,你说得完全正确!我忘记了那个。我会更新答案的。 - Nicolai Parlog
这就是让我困惑的地方! - DJ180
你能解释一下为什么在你的例子中会出现错误信息吗? - DJ180
你的意思是为什么即使该模块不是必需的,它仍然失败了吗?因为模块系统希望每个文件夹都是明确的。一个技术原因是服务绑定,这可能会导致解析不直接所需的模块。但我认为哲学上的原因是同一模块出现两次的文件夹肯定是一个错误更重要。 - Nicolai Parlog
显示剩余2条评论

5

JEP 261描述了模块系统中的模块路径:

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

  • 一个模块构件,即一个包含编译后模块定义的模块化JAR文件或JMOD文件,要么是

  • 一个已爆炸的模块目录,其名称按惯例为模块的名称,其内容是一个对应于包层次结构的“已爆炸”目录树。

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

当搜索某个名称的模块时,模块系统会获取该名称的第一个模块定义。如果存在版本字符串,则会被忽略;如果模块路径的某个元素包含多个具有相同名称的模块定义,则解析失败,编译器、链接器或虚拟机将报告错误并退出。构建工具和容器应用程序有责任配置模块路径以避免版本冲突;模块系统的目标不是解决版本选择问题。正如所解释的那样,这意味着只有当同一目录中存在两个具有相同名称的模块时,编译器才会抱怨。

1
在jar文件的上下文中,目录是什么意思?我认为这行代码在说明:“模块系统采用该名称的第一个模块定义”。这肯定意味着我们仍然可能会遇到许多运行时类路径问题吧? - DJ180
@DJ180 规范中提到的目录是一个包含模块定义的目录(即一个模块化的 Jar 文件,或者一个包含模块定义文件和包的 exploded 目录)。我还不清楚这是否会导致运行时问题(我还没有尝试过这样的情况)。 - M A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接