修补模块引发模块未找到错误

时间:2019-07-29 18:32:30

标签: java java-9 java-module jigsaw

我使用jdk 11并尝试了解Java编译器的--patch-module选项。这是我拥有的简单模块:

mdl-platform
      |
      |
      |___com.test.mdl.platform
      |            |
      |            |___ ...
      |            |
      |            |___Patch.java
      |
      |___module-info.java

module-info.java

module com.test.mdl.plarform {
    exports com.test.mdl.platform;
}

Patch.java

public class Patch { }

我有Patch.java个文件,想用它来修补模块。我尝试过:

I。

$ javac --patch-module com.test.mdl.platform=mdl-plarform/src/main/java/ \
                mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java 
error: module not found: com.test.mdl.platform
1 error

我还运行了一些伪造的模块路径,并且运行良好(生成了有效的class文件):

II。

$ javac --patch-module com.test.mdl.platform=some/fake/path/ \
      mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java 

那么为什么第一个示例失败,但是目录存在并且包含有效的module-info.java,但是即使路径不存在,第二个也可以正常工作?

1 个答案:

答案 0 :(得分:1)

我将留一些关于javac与选项--patch-module一起工作的研究。

I。有效的--patch-module路径和不在模块路径中的模块名称

$ javac --patch-module com.test.mdl.platform=mdl-plarform/src/main/java/ \
                mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java 
error: module not found: com.test.mdl.platform
1 error

这失败。

Javac应用常规module path scan来查找在--patch-module等式(在这种情况下为com.test.mdl.platform)左侧指定的模块。

对于不在模块路径中的该模块,它显然会失败,并且相关的module not found错误是reported。模块com.test.mdl.platform不在模块路径中,因此行为正常。

II。有效的模块名称和伪路径

$ javac --patch-module com.test.mdl.platform=some/fake/path/ \
      mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java 

这工作正常。

原因是javac检查--patch-module参数右侧指定的路径是否正确。 该路径正确,只要它包含(直接或间接)正在编译的文件即可。

com/sun/tools/javac/file/Locations.java中执行检查。可以看出,它只是在Path mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java上循环,使每次迭代成为父级并与some/fake/path/进行比较。

如果路径不正确,则返回null并返回the module is not being patched。在这种情况下,该文件被视为属于未命名模块

III。路径存在,但既不包含module-info.java也不包含module-info.class

$ javac --patch-module java.logging=mdl-plarform \ 
      mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java

这正常。

原因是模块java.logging包含在运行时映像中,并且可以在模块查找期间找到。下一步是在目录中find either module-info.java or module-info.class。在这种情况下,它失败了,因为它不包含它,然后便退回去在成功的运行时映像中查找module-info.class

IV。有效的模块名称和模块路径,但模块名称不匹配

$ javac --patch-module java.logging=mdl-plarform/src/main/java \
      mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java

mdl-plarform/src/main/java/module-info.java:1: error: module name com.test.mdl.plarform does not match expected name java.logging
module com.test.mdl.plarform {
^
error: cannot access module-info
  cannot resolve modules
2 errors

这失败。

module-info.java中指定的目录中找到--patch-module后,将对其进行解析,并且模块名称包含is checked for equality with the name specified in the --patch-module。在这种情况下,我们会出现不匹配的情况,因此会打印出相关错误。

我通过简单地使用常规Java调试器调试javac来检查此行为。因此,这样做的唯一目的是解释问题所描述案件中的情况。