Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Patching module raises module not found error

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?

like image 548
St.Antario Avatar asked Jul 29 '19 18:07

St.Antario


Video Answer


1 Answers

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.

like image 77
St.Antario Avatar answered Oct 18 '22 18:10

St.Antario