module-info.java 放在哪个目录?
In which directory does module-info.java go?
从项目 Jigsaw 的快速入门教程来看,module-info.java 似乎进入了一个带有模块名称的目录,例如,对于模块 my.module包含一个 class MyClass:
bin/
my.module/
module-info.class
my/
module/
MyClass.class
然后,仍然按照教程,在调用 MyClass 时(假设它有一个 method
),模块路径选项被赋予 bin
目录:
java -p path/to/bin -m my.module/my.module.MyClass
到目前为止,还不错。
然而,如果我写:
java -p path/to/bin/my.module -m my.module/my.module.MyClass
而且我不明白为什么两者都有效。
如果 bin
包含两个模块没有区别:如果两个目录都在模块路径中,第二个版本仍然有效(如果只有 bin
在模块路径中,它也有效,如教程中所述)。
现在,当我尝试使用 Eclipse 创建 Maven 项目时,使用 Java 9 个模块,module-info.java 驻留在 src/man/java
目录中,同样,module-info.class 在 target/classes
中。所以现在包含 module-info.class 文件的目录与模块名称无关。
并且 target/classes
也在模块路径中(当我检查构建配置时)。这与上面的第二种情况类似,java -p path/to/bin/my.module -m my.module/my.module.MyClass
。
所以,显然,Java只使用module-info.class的内容来发现模块名,而目录名是任意的?
但是,在第一种情况下,当我写 java -p path/to/bin -m my.module/my.module.MyClass
时,这意味着 Java 将在模块路径中的目录中查找目录。
我觉得我错过了一些重要的东西。 Java在模块路径的目录中查找模块的方式有明确的解释吗?什么真正指定了一个模块? (我的印象是:不是目录,只有模块-info.java)。
让我更加困惑的是:Oracle documentation 指出:
--module-path modulepath... or -p modulepath
A semicolon (;) separated list of directories in which each directory is a directory of modules.
但这显然不是故事的全部,至少 Eclipse 不是如何使用此选项的。
注意:我看过 ,但它并没有真正帮助:一个答案说模块-info.java 进入 src/java/,另一个说它进入一个目录其名称是模块名称。显然两者都是正确的,但他们没有解释为什么,并且存在明显的矛盾。
来自 java.lang.module.ModuleFinder#of(Path...)
的文档:
Returns a module finder that locates modules on the file system by searching a sequence of directories and/or packaged modules. Each element in the given array is one of:
- A path to a directory of modules.
- A path to the top-level directory of an exploded module.
- A path to a packaged module.
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.
If an element is a path to a directory of modules then each entry in the directory is a packaged module or the top-level directory of an exploded module [emphasis added]. It is an error if a directory contains more than one module with the same name. If an element is a path to a directory, and that directory contains a file named module-info.class
, then the directory is treated as an exploded module rather than a directory of modules [emphasis added].
The module finder returned by this method supports modules packaged as JAR files. A JAR file with a module-info.class
in its top-level directory, or in a versioned entry in a multi-release JAR file, is a modular JAR file and thus defines an explicit module. [...]
[...]
当您使用 --module-path path/to/bin
时,路径条目被视为 模块目录 。这是因为 bin
目录(即顶级目录)中没有 module-info.class
文件。
- 据我所知,模块目录中的任何分解模块都不需要有一个top-名称与模块名称匹配的级别目录。这只是一个约定。换句话说,您可以将
my.module
目录重命名为您想要的任何名称; ModuleFinder
只是查看目录以查看是否存在 module-info.class
文件。
当您使用 --module-path path/to/bin/my.module
时,路径条目被视为 分解模块 。这是因为 my.module
目录(即顶级目录)中存在 module-info.class
文件。
- 使用Maven等构建工具时也是如此。
target/classes
目录是一个 分解模块 因为 module-info.class
文件存在于顶级目录中。
不幸的是,我找不到任何说明上述 ModuleFinder
实现在执行 java
时保证在内部使用的内容。但是,很可能使用的是上面的内容。
从项目 Jigsaw 的快速入门教程来看,module-info.java 似乎进入了一个带有模块名称的目录,例如,对于模块 my.module包含一个 class MyClass:
bin/
my.module/
module-info.class
my/
module/
MyClass.class
然后,仍然按照教程,在调用 MyClass 时(假设它有一个 method
),模块路径选项被赋予 bin
目录:
java -p path/to/bin -m my.module/my.module.MyClass
到目前为止,还不错。
然而,如果我写:
java -p path/to/bin/my.module -m my.module/my.module.MyClass
而且我不明白为什么两者都有效。
如果 bin
包含两个模块没有区别:如果两个目录都在模块路径中,第二个版本仍然有效(如果只有 bin
在模块路径中,它也有效,如教程中所述)。
现在,当我尝试使用 Eclipse 创建 Maven 项目时,使用 Java 9 个模块,module-info.java 驻留在 src/man/java
目录中,同样,module-info.class 在 target/classes
中。所以现在包含 module-info.class 文件的目录与模块名称无关。
并且 target/classes
也在模块路径中(当我检查构建配置时)。这与上面的第二种情况类似,java -p path/to/bin/my.module -m my.module/my.module.MyClass
。
所以,显然,Java只使用module-info.class的内容来发现模块名,而目录名是任意的?
但是,在第一种情况下,当我写 java -p path/to/bin -m my.module/my.module.MyClass
时,这意味着 Java 将在模块路径中的目录中查找目录。
我觉得我错过了一些重要的东西。 Java在模块路径的目录中查找模块的方式有明确的解释吗?什么真正指定了一个模块? (我的印象是:不是目录,只有模块-info.java)。
让我更加困惑的是:Oracle documentation 指出:
--module-path modulepath... or -p modulepath
A semicolon (;) separated list of directories in which each directory is a directory of modules.
但这显然不是故事的全部,至少 Eclipse 不是如何使用此选项的。
注意:我看过
来自 java.lang.module.ModuleFinder#of(Path...)
的文档:
Returns a module finder that locates modules on the file system by searching a sequence of directories and/or packaged modules. Each element in the given array is one of:
- A path to a directory of modules.
- A path to the top-level directory of an exploded module.
- A path to a packaged module.
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.
If an element is a path to a directory of modules then each entry in the directory is a packaged module or the top-level directory of an exploded module [emphasis added]. It is an error if a directory contains more than one module with the same name. If an element is a path to a directory, and that directory contains a file named
module-info.class
, then the directory is treated as an exploded module rather than a directory of modules [emphasis added].The module finder returned by this method supports modules packaged as JAR files. A JAR file with a
module-info.class
in its top-level directory, or in a versioned entry in a multi-release JAR file, is a modular JAR file and thus defines an explicit module. [...][...]
当您使用
--module-path path/to/bin
时,路径条目被视为 模块目录 。这是因为bin
目录(即顶级目录)中没有module-info.class
文件。- 据我所知,模块目录中的任何分解模块都不需要有一个top-名称与模块名称匹配的级别目录。这只是一个约定。换句话说,您可以将
my.module
目录重命名为您想要的任何名称;ModuleFinder
只是查看目录以查看是否存在module-info.class
文件。
- 据我所知,模块目录中的任何分解模块都不需要有一个top-名称与模块名称匹配的级别目录。这只是一个约定。换句话说,您可以将
当您使用
--module-path path/to/bin/my.module
时,路径条目被视为 分解模块 。这是因为my.module
目录(即顶级目录)中存在module-info.class
文件。- 使用Maven等构建工具时也是如此。
target/classes
目录是一个 分解模块 因为module-info.class
文件存在于顶级目录中。
- 使用Maven等构建工具时也是如此。
不幸的是,我找不到任何说明上述 ModuleFinder
实现在执行 java
时保证在内部使用的内容。但是,很可能使用的是上面的内容。