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

Reply via email to