Hello all

The compiler plugin has a pull request which is ready for the support of multi-release projects and modular projects defined by the <source> elements introduced in POM 4.1.0. However, the changes are a bit large and I'm not sure how to proceed for review, as it would be a lot of work for reviewers:

   https://github.com/apache/maven-compiler-plugin/pull/320

If this pull request is accepted, there is further development ready for a next pull request. In Maven 3, when a developer needed to alter the module-info for testing purposes, it was suggested to overwrite module-info.java in the test. It doesn't work well, as Java refuses to let someone overwrite module-info (at least in all my attempts), maybe for security reasons. Maven 3 tricked Java by defining the test as the main code and the main code as the patch, which put us at risk of weird behavior. The new compiler plugin also tricks Java but in a different way: it temporarily deletes the main module-info during test compilation, which causes Java to pickup the test module-info. But it still not the way we should proceed.

Instead of overwriting module-info, we are supposed to use --add-modules, --patch-module, --add-reads, --add-exports and --add-opens options, which exist for this purpose. However, declaring these options in the <compilerArgs> element of plugin configuration is tedious, error prone and forces duplication because the same configuration needs to be repeated in at least the Surefire plugin (also Javadoc if test documentation is generated). But the Maven 3 mechanism for overwriting module-info was added because some developers felt a need for it, so maybe just deprecating this practice is not sufficient. Therefore, I propose to replace it by something very similar, but done in the right way.

The proposal is to add a new file, called "module-info-patch.txt", in replacement of "module-info.java" in test. The ".txt" extension is because this file is not standard Java (proposals for better extension are welcome). The content of this file would look like as below (example from a real project):

   patch-module org.apache.sis.storage {
        add-reads org.junit.jupiter.api,
                  org.opengis.geoapi.conformance,
                  esri.geometry.api;

        add-exports org.apache.sis.storage.test
                 to org.apache.sis.storage.geotiff;
   }

The syntax is straightforward: all keywords inside `patch-module` are standard javac option, written in the same way as in `module-info.java`. The advantage of this approach is that it uses a syntax familiar to Java developer and is simpler. For example, the following:

   add-reads org.junit.jupiter.api;

is translated to the following option (note the addition of the module name):

   --add-reads org.apache.sis.storage=org.junit.jupiter.api;

The same applies to other options. The use of a module-info like file avoid the need to repeat the module name in all these options. This proposal is documented in more details there:

   
https://github.com/Geomatys/maven-compiler-plugin/wiki/User-guide#compilation-of-tests

Other plugins do not need to know how to parse this `module-info-patch` file, as the compiler plugin would generate a `target/test-classes/META-INF/test/jpms.args` file (or something like that) for use by other plugins. This proposal is already implemented and tested on a real project (a clone of Apache SIS) for the compilation part, and works well so far. I would like to see if there is any discussion about this proposal. If accepted, it would be the next pull request after the one mentioned at the beginning of this email.

    Martin

Reply via email to