RFE simplify usage of patched module [by Robert Scholte, from jdk-dev]
Christian Stein
sormuras at gmail.com
Sat Feb 15 05:34:36 UTC 2020
On Fri, Feb 14, 2020 at 10:31 PM Alex Buckley <alex.buckley at oracle.com>
wrote:
> On 2/14/2020 11:29 AM, Christian Stein wrote:
> >> 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.
> >
> > That's too late in the build game. You already need this merged
> > descriptor at compile time. And you need the user to define the
> > additional elements (modifiers and directives), as no build tool
> > may infer them always correctly by inspecting the test sources...
>
> Fair point, and thanks for reminding me about your "Testing In The
> Modular World" document.
>
> The thing I'm having trouble with is that javac already lets you specify
> the --add-reads options on org.junit.jupiter.api & friends that are
> needed to compile test code. If Maven expects the user to painfully
> configure the POM to pass --patch-module-descriptor to javac, why can't
> the POM offer an easy way to make Maven itself (in the `test-compile`
> phase?) pass some defined-behind-the-scenes --add-reads options?
>
>
Maven and other build tools would add the `--patch-module-descriptor`
automacially and point to the user-defined "patch module compilation unit"
that only contains the extra directives: like `requires java.sql;`, or
`requires org.testng.core;` or ... `requires org.junit.jupiter;`. Or all of
them.
Those extra directives needed by test modules to compile and run
are a deliberate decision made by the user -- on a per test module basis.
No build tool may infer those decisions correctly.
Similarly, at run time, you propose to always open the main module to
> the same org.junit.platform.commons module -- `module-info.test` is more
>
Not the main module. Only the current test module. Assuming, that you
run tests from a single test module at a time.
> or less the same for every JUnit project -- so why doesn't the POM have
> an easy way to let Maven itself (in the `test` phase?) pass --add-opens
> to java?
>
Opening a module for deep-reflection is just a single aspect of the
"Testing In The Modular World" story. Btw. `open module` or `--add-opens`
is only required iff the test framework of choice reflects into your test
modules. I already have a ServiceProvider-based variation running locally,
that uses this standard technique to pass the execution control to the
main-like entry-point of each test module.
> There are no new modularity "primitives" here (by which I mean features
> of the module system itself, such as open modules) ... there is just
> detailed configuration which, in the testing context, should be done by
> the build tool rather than the user.
>
Except for configuration parts that cannot be inferred. Here the user
has to resort to javac and java command line options, like `--add-reads`,
and must negotiate with the build tool how to pass those options.
And all of this tedious and errorprone textual configuration **after**
having declared a concise, tool-agnostic, well-definend and beautiful
inter-module test module using the official `module-info.java` syntax:
- test.base/test/module-info.java:
open /*test*/ module test.base {
requires com.greetings; // module under test
requires org.astro; // module under test
requires java.sql; // system-provided module needed by test code
requires org.junit.jupiter; // framework reflecting entry-points
requires org.assertj.core; // ...and more test-related modules
}
Leaving this compile-able DSL behind **only** for in(tra)-module
(white-box) testing is ... inconvenient and hard to explain. Like
Robert wrote in his initial request to simplify the usage of patch
module.
Assuming `--patch-module-descriptor` was already available, the
org.astro test story would read:
- org.astro/main/module-info.java:
module org.astro {
exports org.astro;
requires java.logging;
}
- org.astro/test/module-info.java:
open /*test*/ module org.astro /*extends main module org.astro*/ {
requires java.sql; // system-provided module needed by test code
requires org.junit.jupiter; // framework reflecting entry-points
requires org.assertj.core; // ...and more test-related modules
}
A build tool now easily may detect that `--patch-module-descriptor`
is required at test compile and run time. It could infer it from the
same module name or simply by seeing a main and a test
`module-info.java` compilation unit within the sources of the
org.astro Maven-/Gradle-/pro-/Bach-/any-build-tool-"module".
Build tools could pass the following argument to javac/java
while being in their test-scope tasks. Of course, implying that
org.astro/test/module-info.java is the current "primary" module
descriptor:
--patch-module-descriptor org.astro=org.astro/main/module-info.java
That's it.
The primary test-relevant modular directives are enriched by
those of the main module as declared in org.astro/main/module-info.java
resulting effectively in a synthetic in-module test module descriptor that
resembles the inter-module test descriptor presented above:
- SYNTHETIC test module for org.astro
open /*test*/ module org.astro /*extends main module org.astro*/ {
requires java.sql; // system-provided module needed by test code
requires org.junit.jupiter; // framework reflecting entry-points
requires org.assertj.core; // ...and more test-related modules
//
exports org.astro; // patched from org.astro/main/module-info.java
requires java.logging; // patched from org.astro/main/module-info.java
}
Cheers,
Christian
More information about the jigsaw-dev
mailing list