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

Reply via email to