Hello all
I'm not yet ready to submit a pull request for the reworked
maven-compiler-plugin, but I would like to report some details about
changes that would come, if accepted. This work is for Maven 4 only, the
plugin for Maven 3 will stay unaffected.
As proposed on GitHub comment [1], I'm modifying the implementation for
using the standard javax.tools.JavaCompiler interface instead of the
Plexus compiler. That interface is part of standard JDK since Java 6. It
seems that the Eclipse compiler provides also an implementation of that
interface, so compiler independence should be preserved. Forked
compilation is handled by a custom implementation of that interface. The
javax.tools.JavaCompiler interface has some methods needed for Java
modules, for which I saw no direct equivalence in Plexus API. The gap
may grow larger if future Java versions bring more evolution to the
compiler API. The standard interface also has a cache mechanism that may
bring performance improvements (to be verified) when compiling more than
one set of sources, e.g. for multi-versions. It also opens the door for
handling source and classes that are not files, for example by doing
everything in memory (I have no plan to use this features now, but it
become a possibility for the future).
The way to handle compiler options has been modified. Previously, the
Maven plugin validated some options before to pass them to the compiler.
For example, if the <debuglevel> value contains anything else than
"lines", "vars" or "source", the plugin raised an error. The intend was
to provide more informative message. But in the javax.tools.JavaCompiler
interface, there is an API telling us whether an option is supported.
Therefor, the new plugin version first asks to the compiler whether the
option is supported, and only if the compiler said "no", the validation
is performed for producing the error message. Consequently, if the
compiler claims to support the "-g:foo" option, then the plugin will no
longer block the use of the "foo" value in <debuglevel> even if the
plugin does not know that value.
The set of plugin parameters is the same as before: no addition and no
removal, but there is some deprecation. Of course, what to deprecate or
not is open to discussion. In the current state of work, the following
parameters are deprecated but are still working:
* <compilerArgument> (a single String): already replaced by
<compilerArgs> (a list of Strings) since Maven 3.1.
* <annotationProcessorPaths>: replaced by ordinary dependencies with
<type>proc</type>, a new artifact type introduced in Maven 4-alpha13.
The following parameters are marked as deprecated for removal in the
current state of work. They all became no-op in the new plugin:
* <forceJavacCompilerUse>: the documentation is not really explicit,
but it seems to be about forcing the use of java.lang.Compiler
instead of javax.tools.JavaCompiler (it does not seem to be about
the javac command). The java.lang.Compiler class was deprecated
since Java 9 and no longer exists in Java 21.
* <outputFileName>: bundling many class files into a single file can
be considered as the task of separated plugins, for example the JAR
plugin. Furthermore, this parameter does not fit well in the context
of Module Source Hierarchy, because the output is not a single JAR.
* <compilerReuseStrategy>: the way that the javax.tools.JavaCompiler
API is designed, this parameter does not seem relevant to instances
of that interface. The parameter may be partially relevant to some
objects used by JavaCompiler, but not fully (e.g. the "reuseSame"
parameter value stay inapplicable). I suggest to let those decisions
as plugin implementation details.
* <skipMultiThreadWarning>: deprecated as a consequence of
<compilerReuseStrategy> deprecation.
The following parameters had their default value modified:
* <source> and <target>: removed the default value and added a Javadoc
saying "As of Java 9, the --release option is preferred." Its
default value (if any) has not yet been chosen.
Finally, the CompilerMojo and TestCompilerMojo subclasses contained
magic in their preparePaths(…) method for trying to setup automatically
some values of --patch-module and --add-reads options. This was done for
multi-versions and for tests compilation. This magic has been removed
for now (I will see during the tests if we need to bring back some). To
avoid black magic or make it more controllable is the whole purpose of
this effort in improving JPMS support.
I have not yet reached the point where tests can be done. This email is
only for reporting progress, and see if there is discussion.
Martin
[1]https://github.com/apache/maven/pull/1401#issuecomment-1974810724