Minor correction: the classes method will necessarily *detect* added
sources, because they won't have a class file.
What occurs as a result is another matter./
It might be worth considering forcing a full build as an option in
such cases if there is any way that adding a new source file can
affect the compilation of others.

On Mon, 22 Apr 2024 at 13:52, Martin Desruisseaux
<martin.desruisse...@geomatys.com> wrote:
>
> Hello all
>
> The Maven compiler plugin has an <useIncrementalCompilation> boolean
> parameter with `true` as the default value. This parameter has issues
> discussed in MCOMPILER-209 [1], which has 61 votes. In short, builds are
> much faster when this parameter is set to `false`, which is
> counter-intuitive. During the refactoring for the Maven 4 compiler
> plugin, by looking at the source code, I saw the following issues with
> the current implementation:
>
>   * When <useIncrementalCompilation> is enabled (which is the default),
>     the plugin compares the list of source files in the current build
>     with a list saved after the previous build in order to detect
>     changes. But it seems to me that the plugin uses relative paths in
>     one case, and absolute paths in the other cases. Consequently, the
>     paths do not match and the plugin always thinks that all source
>     files changed. I did not double-checked or tested (maybe I missed
>     some `toAbsoluteFile()` calls). But if confirmed, it would explain
>     the MCOMPILER-209 issue.
>   * The ways that the two lists are compared has a performance cost of
>     O(N²). It could easily be O(N) instead by replacing one list by an
>     hash set.
>   * The plugin tries to detect changes in dependencies, but the
>     algorithm works only if the compilation never fail. Consider the
>     following scenario:
>       o One project has 3 modules: A, B and C.
>       o Module B and C depends on A.
>       o Developer makes a change in A and run `mvn install`.
>       o Module A compiles successfully, but B fails because of the
>         change in A.
>       o Developer fixes the build failure in B and run `mvn install`
>         again. In this scenario, the incremental compilation will not
>         see that C also needs to be rebuilt, because when
>         <useIncrementalCompilation> is enabled, the plugin compares the
>         JAR timestamps with the build start time. In this scenario, the
>         second build start time is after the `A.jar` creation time.
>         Maybe this issue was unnoticed because the issue explained in
>         the first bullet point caused the plugin to always recompile
>         everything anyway.
>
> I propose to deprecate <useIncrementalCompilation> in Maven 4 and
> replace it by a new parameter: <incrementalCompilation>. Its value would
> be a comma-separated list of values instead of a single boolean flag.
> Those values specify which methods to use for deciding which files to
> recompile:
>
>   * "sources": check for changes in source files, including whether a
>     file has been deleted. This method uses a file saved by the previous
>     build in the "target/maven-status"  directory (as done by the
>     current implementation).
>   * "classes": check whether the source file is more recent than the
>     class file. This method does not need any "maven-status" file from
>     the previous build, but does not detect whether a file has been
>     added or removed.
>   * "dependencies": check whether a dependency has changed (using a more
>     robust algorithm than the current one).
>   * "modules": do not specify any file to the compiler and use the
>     `--module` option instead, in which case the compiler will scan the
>     directories itself and decides itself which files to recompile based
>     on their timestamp. This option is available for modular projects only.
>
> The current <useIncrementalCompilation> boolean flag maps to above
> proposal as below:
>
>   * `true` is approximately equivalent to "sources,dependencies", except
>     that I propose to not rebuild everything when a file is added (it is
>     usually not needed).
>   * `false` is equivalent to "classes".
>
> As seen from above, the current <useIncrementalCompilation> actually
> mixes two aspects that could be treated separately: whether to check if
> a dependency changed, and whether to use a list saved from the previous
> build for checking if a source file changed. The comma-separated value
> proposal would allow users to control those aspects independently.
>
>      Martin
>
> [1]https://issues.apache.org/jira/browse/MCOMPILER-209

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org

Reply via email to