On Wed, 2 Oct 2024 at 11:29, Martin Desruisseaux <martin.desruisse...@geomatys.com> wrote: > 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.
This issue remains hugely painful not just in Maven, but across Java. It is a key part of why JPMS adoption is so painful. The key principle here is that tests for a Maven module should be located *within* the same Maven module of the main source code. Forcing developers to write a separate Maven module just for tests is not an acceptable solution. 1) Classpath testing with one (main) module-info.java file. IIUC, this is what you are planning for maven-compiler-plugin and maven-surefire-plugin to support. It tests with the main code on the modulepath and the test code on the classpath. While this is fine for many use cases, sometimes you really need to run the tests on the modulepath, so this is not sufficient by itself. 2) Blackbox testing with two module-info.java files. This is supported by IntelliJ and Gradle IIUC. Maven must support this IMO. For maven-compiler-plugin, Blackbox tests are fine AFAICT. All the files in src/test/java are in a different package, and the module-info.java file refers to a different module name, so there are no clashes. The maven-surefire-plugin would just put the main module and the test module on the modulepath, and everything ought to be fine. I believe Gradle recommends src/integrationTest for blackbox tests, and I think that convention makes a lot of sense. It offers up the potential for a single Maven module to contain both whitebox and blackbox tests, which is incredibly powerful. 3) Whitebox testing with two module-info.java files. This has yet to achieve an agreed approach in the community, despite JPMS being out for many years. To work effectively, it might be beneficial for the module-info file to be named module-info-whitebox.java, or alternatively be in src/whitebox. Option A) "Parse and Patch" maven-compiler-plugin would find the whitebox module-info source file, parse it directly and convert it to command line options based on --patch-module. maven-compiler-plugin would then compile the test classes excluding the whitebox module-info source file using the derived command line options. maven-surefire-plugin would use the same derived command line options. Option B) "Merge and Recompile" maven-compiler-plugin would compile the test classes by including both src/main/java and src/test/java as inputs, excluding the src/main/java/module-info.java file maven-surefire-plugin would run only with target/test-classes, not target/classes Option C) "Copy before Compile" maven-compiler-plugin would first copy target/classes to target/test-classes excluding target/classes/module-info.class maven-compiler-plugin then compiles src/test/java to target/test-classes, without using target/classes as an input maven-surefire-plugin would run only with target/test-classes, not target/classes I believe Option A is more desirable, and more in the spirit of JPMS, and more in the spirit of Maven. I understand that you want to make defining patch-module directives easier in pom.xml. While that's a lovely idea, I think it is fundamentally flawed in usability. There is no connection in the mind of a developer between module-info directives and the matching command line arguments. By contrast developers know exactly how to setup the module-info.java file. The only real difference I'm proposing is that the patch-module directives are not defined in pom.xml, but are instead defined in a java-like source file, eg module-info-whitebox.java. Think of it as a Maven config file which happens to look like a java source file and it really isn't that scary. ( I think it makes sense for this to be part of maven-compiler-plugin, but it could also be a separate plugin that runs before maven-compiler-plugin, or a separate goal. For example, it could be thought of as a converter/compiler from module-info-whitebox.java to module-info-whitebox.javac.args) Stephen --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@maven.apache.org For additional commands, e-mail: users-h...@maven.apache.org