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

Reply via email to