Hello Stephen
Thanks for testing.
Le 2024-10-02 à 00 h 30, Stephen Colebourne a écrit :
At present, the compile phase is asked to compile module-info.java,
but the target/classes directory does not contain module-info.class.
I've no idea where it is going I'm afraid.
Is module-info missing for both test and main, or only for test?
the current prototype does not allow anymore to have module-info in
both main and test. The latter is replaced by automatically generated
compiler options.
I don't believe this is the right direction to go. The command line
flags are difficult to understand, and connect to the matching meaning
in module-info.java. By contrast, simply specifying a testing
module-info.java directly expresses what needs to be expressed.
Furthermore, IntelliJ already supports BlackBox testing in
src/test/java, plus it is the recommended approach on the Maven
website, so I don't think it is viable to remove that.
The problem with module-info in both tests and main is that it works
awkward. The previous compiler plugin had to took the project structure
upside-down: the test code was considered the main code, and the main
code was considered the patch. I just checked by compiling and running a
dummy project with `java` and `javac` directly (without Maven) and I
confirm: even if a `module-info` is present in the test output, it is
ignored by the `java` command (the `module-info` of the main code has
precedence) unless we pretend that the test are the main code and the
main code are patching the tests. The behavior of `javac` is a little
bit more complicated, but basically we also have to put things upside
down to make it works.
If nevertheless we still want to support having `module-info` in both
main and test, I found a trick this morning for getting `javac` to
compile the test `module-info` without putting the project structure
upside-down. But it is undocumented and I don't know how reliable it
would be. I can implement this trick (or try other tricks) if this is
important, but I think that we should stop recommending the approach of
overwriting `module-info`, or recommend to use it in last resort only.
The alternative (compiler options) is indeed tedious, but this is
precisely a major goal of this JPMS work to make that task easier than
it currently is.
As a separate point, it is very hard to know what the plugin is doing.
AFAIK, the only approach to finding out what is going on is to use -X
which produces far too many logs.
Indeed, the current beta-2 compiler generates a `javac` file somewhere
in the `target` directory with the arguments that it used, but only if
the compilation fails or if Maven was launched with the `--debug` flag.
My rational was that the developer may not be interested in details when
the compilation is successful. But we can of course revisit that policy.
Otherwise, you can ignore the verbose logs of -X and just look for that
`javac` file (I forgot the exact name) in `target`.
(And as a side note, I agree that Maven is too verbose, even in
non-debug mode).
* In project dependencies, add <type>modular-jar</type> for forcing
the compiler to put the JAR dependency on the module path instead of
trying to guess.
* Conversely, use <type>classpath-jar</type> for forcing the compiler
to put the JAR dependency on the class-path.
I can't see many people wanting to set these. They are also
restricting. (I believe use of these setting would mean that I cannot
be used to run the same tests three times, as I am currently doing
with Maven 3)
The current Maven 3 behavior is still supported: <type>jar</type>
(without specifying "modular-jar" or "classpath-jar") behaves as today,
with the same heuristic rules. The "jar" type is still the default, so
being specific is an "opt-in" feature.
Regarding white-box testing in a modular project:
* The plugin uses the --patch-module option for specifying the
directories of test classes to the Java compiler.
* The plugin adds the following options for test dependencies that are
not present in the main dependencies (typically JUnit):
o --add-modules and --add-reads for compile-time dependencies.
o --add-modules only for runtime-time dependencies (typically
services to be discovered with java.util.ServiceLoader).
o --add-reads ALL-UNNAMED if at least one compile-time test
dependency is not modular.
You also need to ensure that
- src/main/resources and src/test/resources are correctly patched
- the module-info.java `requires static` directive is correctly followed.
Yes, but those last points apply more to the surefire plugin than the
compiler one. We did not started the work on surefire yet.
Martin