On 2/14/2020 12:02 AM, Robert Scholte wrote:
To me having the correct (main) module descriptor should be the ultimate goal. People should not be tempted to apply workarounds on this descriptor to make things work for tests (even though those module are for sure part of the java runtime) Especially because of the impact wrong module descriptors would have and which cannot be adjusted.
Nowhere else in Java is there the ability to "patch" one declaration by making further declarations in source code, so I don't think there's a way forward for a `patch module ...` declaration. I understand that it looks good when viewed through the lens of testing, where there's exactly one secondary module declaration (the test module) and it's tightly scoped to support white-box tests. However, we have to consider if it's a good idea in general for a module to be defined by parts, where anyone could throw multiple `patch module foo {..}` declarations on the module path and have each of them modify the "master" foo module.
The answer is that it's not a good idea: (i) different `requires` clauses might clash (i.e. read modules which export the same packages), (ii) one patch might `open` the module while another patch doesn't want it open (and there's no way to say non-open), and (iii) the content of packages in the unified module is now determined by the order in which the "master" module and the "patch" modules are deployed on the module path.
These things are so undesirable that even `--patch-module` is unable to override module declarations! That said, command line options can have superpowers that would never be expressible in source code declarations, so one option might be a `--patch-module-descriptor` option. This would be orthogonal to `--patch-module`, which deliberately has leaky classpath-style semantics for its specified content, and that's neither desirable nor useful here. Within limits, `--patch module-descriptor` would merge the declaration of the "patch" module into the "master" module, and fail hard if the limits are broken. What are the limits? A starting point is the rules for versioned module descriptors in a modular multi-release JAR -- http://openjdk.java.net/jeps/238#Modular-multi-release-JAR-files -- and perhaps it's reasonable to allow additional _qualified_ exports in the "patch" module.
Now, I am not "proposing" `--patch-module-descriptor` for a future JDK. I am recognizing that certain use cases involve changing a module's dependences and encapsulation in a tightly scoped way. A different way to address those use cases would be to ship the logic just described for `--patch-module-descriptor` in a launcher offered by the test framework itself. If JUnit creates its own module layer, then it can define module descriptors at run time how ever it likes. It's not clear to me if Christian & co. have looked into java.lang.ModuleLayer, java.lang.module.Configuration, and java.lang.module.ModuleFinder. If they have, we'd love to hear their experiences. If they haven't, they should.
Alex