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