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



我使用 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文件,想用它修补模块。我试过了:

我。

$ 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文件):

第二。

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

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

我将留下一些关于javac如何使用选项--patch-module的研究。

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

此操作失败。

Javac应用常规模块路径扫描来查找--patch-module相等性左侧指定的模块(在此特定情况下com.test.mdl.platform)。

对于不在模块路径中的此模块,它显然失败并报告相关的module not found错误。模块com.test.mdl.platform不在模块路径中,因此行为是预期的。

二、有效的模块名称和虚假路径

$ 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 中执行。可以看出,它只是在每次迭代中获取父级并与some/fake/path/进行比较Pathmdl-plarform/src/main/java/com/test/mdl/platform/Patch.java循环。

如果路径不正确,则返回null并且不会修补模块。在这种情况下,该文件被视为属于未命名的模块

三、路径存在,但既不包含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包含在运行时映像中,并且可以在模块查找期间找到。下一步是在目录中查找module-info.javamodule-info.class。在这种情况下,它会失败,因为它不包含它,然后它会回退以在运行时映像中查找成功的module-info.class

四、模块名和模块路径有效,但模块名不匹配

$ 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

此操作失败。

--patch-module中指定的目录中找到module-info.java后,对其进行解析,并检查它包含的模块名称是否与--patch-module中指定的名称相同。在这种情况下,我们不匹配,因此打印了相关错误。

我通过简单地使用常规 java 调试器调试javac来检查此行为。因此,这样做的唯一目的是解释问题中描述的案例中发生了什么。

最新更新