Le 2024-10-11 à 10 h 21, Stephen Colebourne a écrit :
(…snip…, was about module-info duplicated in main and tests)
This issue remains hugely painful not just in Maven, but across Java.
It is a key part of why JPMS adoption is so painful.
I don't think that adoption is painful because of JPMS, since I think
that there is good security reasons for the way that it works. I believe
adoption is painful because Maven and Gradle are not helping. I hope
that the new compiler plugin will demonstrate that (I didn't had the
time to work on it during the last month, sorry for that).
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.
Yes, we agree on that. But it doesn't change with JPMS, there is no need
to put the tests in a separated module. Overwriting a module-info in the
tests should be a deprecated practice, as there is better alternatives
(again, with Maven's help for making that easy). If nevertheless a
developer really wants to overwrite the module-info, it is possible with
better hacks than what the current plugin does (e.g. we could
temporarily move the main module-info).
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.
No, this is not what I plan to do. My plan is to test everything on the
module path (for modular projects), with a single module-info specified
in the main code. The test-only dependencies are handled by
--add-modules and --add-reads options added automatically by Maven based
on what is declared in POM <dependencies> section (so developers have
control). The test classes in the same packages as the main classes are
handled by --path-modules options added automatically by Maven. JUnit
execution needs --add-opens options to be added by automatically by
Maven too (the way to keep that part under developer's control has not
been determined yet). So there is usually no need to overwrite the
module-info in the test code.
There are a few cases where overwriting module-info in test code may be
necessary. For example, I'm not aware of any Java option for adding or
removing services (the "provides" clause in module-info). So this is a
case where overwriting module-info may be necessary, but it should be a
minority of cases, to use in last resort only. And as said above, for
those cases, hacks are still possible.
2) Blackbox testing with two module-info.java files. This is supported
by IntelliJ and Gradle IIUC. Maven must support this IMO.
If the two module-info files declare a different module name and there
is no package name collision, indeed this would be a good think to add.
I will put that on my "TODO" list for a future version.
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.
Indeed, I agree we should support something like that out-of-the-box.
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.
If the two module-info files declares the same module name with the
intend that the test one overwrite the main one, we can do with a hack
different than the current one (without putting the project
upside-down). But it should be a deprecated practice, to use in last
resort only. For the majority of cases, we don't need two module-info
for whitebox testing with everything on the module path (see point 1 above).
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.
I'm not proposing to add a new syntax in pom.xml for patch-module
directives. Every time that a test directory has the same packages as
the main code, a patch-module directive must be added. The rule is clear
and simple because otherwise the JVM refuses to launch. So patch
directives are added automatically with no need for the developer to
think about that. For the --add-modules and --add-reads directives, this
is also automatic with clear rules based on the scope of dependencies.
The only directives at this time for which I do not yet have a rule that
I can map to existing Maven concepts is --add-opens.
Martin