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

Reply via email to