问题
I use jdk 11 and try to understand --patch-module
option for java compiler. Here is the simple module I have:
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 { }
I have Patch.java
file and wanted to patch the module with it. I tried:
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
I ran also some fake module path and it worked fine (produced a valid class
file):
II.
$ javac --patch-module com.test.mdl.platform=some/fake/path/ \
mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java
So why did the first example fail, but the directory existed and contained valid module-info.java
, but the second worked ok even the path did not exist?
回答1:
I'll leave some research regarding how javac
works with the option --patch-module
.
I. Valid --patch-module path and module name which is not in module path
$ 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
This fails.
Javac
applies regular module path scan to lookup the module specified in the left hand side of --patch-module
equality (com.test.mdl.platform
in this particular case).
For this module which is not in module path it obviously fails and the related module not found
error is reported. The module com.test.mdl.platform
is not in the module path so the behavior is expected.
II. Valid module name and fake path
$ javac --patch-module com.test.mdl.platform=some/fake/path/ \
mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java
This works "ok".
The reason is that javac
checks the path specified in the right hand side of the --patch-module
argument for correctness. The path is correct iff it contains (either directly or indirectly) the file being compiled.
The check is performed in the com/sun/tools/javac/file/Locations.java. As can be seen it is simply loops over the Path
mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java
getting parent on each iteration and comparing with the some/fake/path/
.
If the path is incorrect then null
is returned and the module is not being patched. The file is treated as belonging to the unnamed module in this case
III. Path exists, but contains neither module-info.java
nor module-info.class
$ javac --patch-module java.logging=mdl-plarform \
mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java
This works ok.
The reason is that the module java.logging
is contained in the runtime image and can be found during module lookup. The next step is to find either module-info.java or module-info.class in the directory. In this case it fails since it does not contain it, then it falls back to lookup the module-info.class
in the runtime image which succeeds.
IV. Valid module name and module path, but module name mismatch
$ 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
This fails.
After the module-info.java
was found in the directory specified in the --patch-module
it is then parsed and the module name it contains is checked for equality with the name specified in the --patch-module. In this case we have a mismatch so the related error is printed.
I checked this behavior by simply debugging javac
with the regular java debugger. So the only intention of that was to explain what was going on in the cases described in the question.
来源:https://stackoverflow.com/questions/57259605/patching-module-raises-module-not-found-error