Le 2025-05-16 à 15 h 01, Andy Law a écrit :
OK. I see the purpose of the <module> tag now.
To elaborate on the purpose of <module>: we could argue that javac
should be able to discover this information itself by parsing the
module-info file. But a single module can have its source files split in
many directories (actually, we enumerate all files to `javac` rather
than specifying directories, and those files could be located anywhere),
and only one of those directories will have a module-info file. For any
additional directories (e.g. as we did before with the `add-source` goal
of `build-helper-maven-plugin`), `javac` has no way to guess in which
module the files belong if there is no `module-name` argument. This is
the reason why the `--module-source-path` compiler option and the
`setLocationForModule` method of `javax.tools.StandardJavaFileManager`
need a `moduleName` argument, and the value of that argument is taken
directly from the `<module>` XML element.
An example of case where we split the source code in many directories is
multi-releases JAR file. When we combine multi-releases with
multi-modules, the `javac` compiler needs to know which module we are
patching with code for a different Java release. There is usually no
module-info file providing this information in the directories of more
recent releases.
Instinctively, I would have applied that at the <project> level and
mapped one project to one module (and built multiple modules as an
aggregation of multiple projects)
In addition to my impression that aggregation is not really natural in
Maven, I think that this instinct would be different for Maven users who
get used to the new <sources> element. This <module> element is part of
a bigger picture including <targetVersion> element (for multi-releases),
unification of the way to specify Java files and resources, unification
of the way to filter files, native support of sources split in many
directories (without the need to use `build-helper-maven-plugin`). If we
forget <module> at first and just get used to <sources>, I think that
after this point, <module> in <source> appears more natural.
Furthermore, technically, trying to hide JPMS behind subproject
aggregation would not work, or at least not directly. Users would expect
the *.class files of each module to be in the target directory of each
subproject, but this is not what `javac` produces. We would have all
*.class file in the target directory of the parent project, split in
directories having the module name: `target/${module}/**/*.class` where
${module} is the value of the <module> element and is generated by
`javac` itself, not by us. Unless the Maven compiler plugin move files
around after the compilation, users would not get what they were used
too anyway.
The Java platform is evolving, and JPMS is part of this evolution.
Nobody is forced to adopt it, but those who would like to embrace JPMS
fully will need to change some habits anyway. Resisting to that
evolution may be more trouble for latter, if some future JPMS features
become more and more difficult to support without embracing the JPMS
model (only for users who want it).
Martin