Le 2024-01-03 à 21 h 31, Romain Manni-Bucau a écrit :
Can you compile this test case with the dependency on the class-path,
without omitting the module-info in the compilation?
This is exactly the case, module-info is injected somehow - a common
case is by generating its bytecode but multiple compiler executions is
another case.
I'm talking about the case where developers write their own code,
including the module-info.java file. You confirm that this test case in
uncompilable with class-path?
I presume that "multiple compiler executions" means "compiling only a
subset of the project". The situation is the same: module-path works,
class-path does not work unless the module-info.class file is deleted. I
updated the README with step-by-step instructions for anyone to try:
https://github.com/Geomatys/MavenModulepathBug/tree/modularized-client
Finally, if some developers want to inject a generated module-info.class
file *after* compilation, then class-path works. But the developers lost
all compile-time safety regarding module encapsulation. Nothing prevent
the developers to accidentally use non-exported packages, in which case
compilation will wrongly succeed but an exception will be thrown at
runtime when the code attempts an unauthorized access. So no, class-path
doesn't work for JPMS projects, except by tricking Java with
module-info.class injection *after* compilation. I would discourage that
trick because:
* The whole project loses all compiler verification of package
accesses, resulting in potentially unexecutable application because
of code that should not have been allowed to compile.
* Errors in the generated module-info.class itself (e.g. missing
"requires" statements, wrong "provides" statements, etc.) will also
be unnoticed at compile-time.
* Adding a class generation phase is more complicated than handling
module-info like ordinary source code and letting javac do its job
(with the added benefit of letting javac do all the verification).
* Module-info is rich (requires, transitive requires, static requires,
exports, qualified exports, opens, qualified opens, uses, provides,
javadoc, etc.). I don't think that generated code can reflect
developers intend as accurately than hand-written module-info.
Before to argument on each point, let focus on the first one. There is
no way (to my knowledge) someone can use class-path without scarifying
compile-time checks of package accesses. However, if someone really
wants to do that anyway, it will still be possible. But it is not the
approach that I'm trying to make easy. The approach that I'm trying to
make easy is the sane way, which is module-info (either .java or .class)
available at compile time, which mandates the use of module-path (I'm
talking only of JPMS projects here). The claim that class-path is the
way to go in JPMS projects is demonstratively false, proven by above
test case. Class-path in JPMS project is unsafe at best, or doesn't work
at all otherwise. If I'm wrong, I need to be convinced by test cases.
Not email arguments, test cases.
Now, enhance your example to consume a jar where implicit module name
would be invalid for example, how would you compile?
If the implicit name is wrong, I want a compilation error. Why would I
want a compilation success followed by a runtime failure? Furthermore,
this counter example is moot, because by the rules explained in previous
emails, that JAR file would be placed on the class-path by default since
it has no module-info and no Automatic-Name manifest attribute. Anyway,
users can also explicitly request to put any dependency on the class-path.
javadoc:javadoc ->
https://github.com/apache/maven-javadoc-plugin/blob/master/src/main/java/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.java#L4420
This link shows that current Javadoc plugin has some JPMS support. The
compiler plugin also has its own (problematic) support, and each plugin
does that in a different way. So this link does not mean that there is
no problem to resolve.
Martin