2

我有一个名为myModule. 在其中,还有另一个名为myPackagemy的文件夹Main.class

旁边myPackage有我module-info.java要编译的。首先看一下文件夹层次结构:

--  myModule
    --  myPackage
        --  Main.class
    --  module-info.java

问题是当我想module-info.java用以下命令编译我的:

javac module-info.java

我收到以下错误:

package is empty or does not exist: myPackage

但是,当我将 Main.java 放在 myPackage 中,然后使用相同的命令编译这两个文件时:

javac module-info.java myPackage/Main.java

错误消失。我不明白为什么会发生这种情况?

4

1 回答 1

1

TL;DR module-info.java文件并非设计为独立的东西。它被设计为多源文件编译单元的一部分。包含模块描述符的单元,以及 至少一个其他文件。


长篇大论的版本

„<em>...还有一个名为myPackage我的文件夹Main.class...</em>“</p>

我会假设你打算打字Main.java,这Main.class是一个疏忽,因为......</p>

  1. 你没有提到它是一个已经编译的字节码文件。
  2. 我想不出有人会故意.class文件放在源目录中的原因。

我还要假设——尽管你在问题中根本没有提到它——你故意遵循Project Jigsaw:模块系统快速入门指南中推荐的约定……</p>

„<em>...按照惯例,模块的源代码位于模块名称的目录中...</em>“</p>

我已经确定如果您的myModule模块只是一个空module{}块,编译会成功。也就是说,如果它没有声明它exports myPackage。所以我还要假设你的module-info.java,就像我的实验一样,包含......</p>

module myModule { 
    exports myPackage;
}

请记住该javac工具的设计目的......</p>

描述

javac命令读取包含用 Java 编程语言编写的模块、包和类型声明的源文件……</em>

还要考虑JPMS 的可靠配置目标……</p>

可靠的配置,用程序组件声明相互之间显式依赖的一种方法来替换脆弱、容易出错的类路径机制

如果我每周六签了一份合同给你修剪草坪,但后来再也没有出现,我有多可靠?想象一下,为声称javac导出包的模块编译 module-info.java 文件是否合法,但该包中没有类。这样的模块有多可靠?

如果我的构建myModule从 Maven Central 下载了您假设的工件,我可能会import myPackage.*在我的课堂上有一个,结果却发现里面什么都没有。一个什么都没有的包有什么用?

„<em>问题是当我想使用以下命令编译我的 module-info.java 时: “</p>

javac module-info.java

myPackage谜底的线索是,当目录包含合法源代码时,上述命令会导致相同的错误。

错误消息并未告诉您文件系统目录为空。它告诉您,您声称模块导出的包是空的。空如:编译器对源代码一无所知,您从未将其作为编译单元的一部分传递给它

„<em>...错误消失了。我不明白为什么会发生这种情况?…</em>“</p>

通过执行: javac module-info.java myPackage/Main.java,您将组成一个编译单元,该单元由模块声明它导出的内容组成。这是JPMS 文档指定系统预期使用的方式……</p>

$ javac -d mods/com.greetings \
        src/com.greetings/module-info.java \
        src/com.greetings/com/greetings/Main.java

所以尽管有错别字,但您报告错误的原因很简单:编译一个不包含任何源文件的模块不仅没有意义,就编译器而言,它是一个格式错误的模块。因此,这是非法的。

于 2020-10-06T21:54:13.307 回答