Patching module raises module not found error
Asked Answered
U

1

6

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?

Uncivilized answered 29/7, 2019 at 18:32 Comment(8)
for one it might be trying to override the com.test.mdl.platform module with itself(or another com.test.mdl.platform) possibly when you specify the module-info.java directory in the input. on the other side, for the latter, there is no such possibility given an empty or invalid directory.Dower
@Dower At least for the latter case the reasonable behavior might be to print an error as well I guess. Unfortunately all the documentation I could find was the JEP openjdk.java.net/jeps/261 which did not cover such casesUncivilized
did you compile your all java files?Chaunce
@Uncivilized What happens when you specify just javac --patch-module com.test.mdl.platform=some/fake/path/ ? and the other alternative javac --patch-module com.test.mdl.platform=mdl-plarform/src/main/java/com/test/mdl/platform/Path.java?Dower
@Dower You mean without any files to compile? It prints no input files as expected. I tried a few more examples and noticed that examples like javac --patch-module fake.module=fake/path mdl-plarform/src/main/java/com/test/mdl/platform/Patch.java also work fine so it means invalid --patch-module arguments seem to be simply ignored.Uncivilized
@ErHarshRathore I built the module as a jar file.Uncivilized
I'm not sure what actually you are trying to achieve. For --patch-module you need two things: (1) and existing module, and (2) additional sources outside the module, that should be compiled as if belonging to the module. In the given layout I only see one module containing a file that is called Patch.java but not patching anything since it already belongs to the module. What am I missing?Calamity
@StephanHerrmann The mostly confused thing I did not understand was why fake paths were ignored and no errors were printed (case II). The behavior turned to be as if no patches are made and the file being compiled is treated as if it belongs to the unnamed module.Uncivilized
U
2

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.

Uncivilized answered 31/7, 2019 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.