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

Java 9: Possible to have 2 modules with same name on module path

是否可以在模块路径上有 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描述模块路径如下:

A module path is a sequence, each element of which is either a module definition or a directory containing module definitions. Each module definition is either

  • A module artifact, i.e., a modular JAR file or a JMOD file containing a compiled module definition, or else

  • An exploded-module directory whose name is, by convention, the module's name and whose content is an "exploded" directory tree corresponding to a package hierarchy.

接着描述模块解析机制:

When searching a module path for a module of a particular name, the module system takes the first definition of a module of that name. Version strings, if present, are ignored; if an element of a module path contains definitions of multiple modules with the same name then resolution fails and the compiler, linker, or virtual machine will report an error and exit. It is the responsibility of build tools and container applications to configure module paths so as to avoid version conflicts; it is not a goal of the module system to address the version-selection problem.

正如所解释的,这意味着只有当两个同名模块存在于同一目录时编译器才会报错

没有

模块路径的同一目录下不能有两个同名模块。官方文档并没有把这些信息放在特别显眼的地方——是 the Javadoc of ModuleFinder::of 泄露了它:

It is an error if a directory contains more than one module with the same name.

我通过创建同一模块的两个版本创建了 a small demo project for the module system and 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(强调我的):

The module finder locates modules by searching each directory, exploded module, or packaged module in array index order. It finds the first occurrence of a module with a given name and ignores other modules of that name that appear later in the sequence.

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