This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-compiler-plugin.git
commit d958a62fc0ae2190b5fbcce3d479032eea5638b9 Author: Martin Desruisseaux <[email protected]> AuthorDate: Sun Sep 21 16:37:18 2025 +0200 Do not create empty "generated-sources" when there is no annotation processor to run. This commit takes in account the fact that `-proc:full` was the default before Java 23. --- .../plugin/compiler/AbstractCompilerMojo.java | 58 +++++++++++++++------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java b/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java index 3fad7fe..c65674c 100644 --- a/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java +++ b/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java @@ -24,7 +24,6 @@ import javax.tools.JavaCompiler; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.OptionChecker; -import javax.tools.Tool; import javax.tools.ToolProvider; import java.io.BufferedReader; @@ -213,6 +212,13 @@ public abstract class AbstractCompilerMojo implements Mojo { */ private boolean targetOrReleaseSet; + /** + * The highest version supported by the compiler, or {@code null} if not yet determined. + * + * @see #isVersionEqualOrNewer(String) + */ + private SourceVersion supportedVersion; + /** * Whether to enable preview language features of the java compiler. * If {@code true}, then the {@code --enable-preview} option will be added to compiler arguments. @@ -290,12 +296,16 @@ public abstract class AbstractCompilerMojo implements Mojo { * </ul> * * The default value depends on the JDK used for the build. - * Prior to Java 22, the default was {@code full}, so annotation processing and compilation were executed without explicit configuration. + * Prior to Java 23, the default was {@code full}, + * so annotation processing and compilation were executed without explicit configuration. * * For security reasons, starting with Java 23 no annotation processing is done if neither - * any {@code -processor}, {@code -processor path} or {@code -processor module} are set, or either {@code only} or {@code full} is set. + * any {@code -processor}, {@code -processor path} or {@code -processor module} are set, + * or either {@code only} or {@code full} is set. * So literally the default is {@code none}. - * It is recommended to always list the annotation processors you want to execute instead of using the {@code proc} configuration, to ensure that only desired processors are executed and not any "hidden" (and maybe malicious). + * It is recommended to always list the annotation processors you want to execute + * instead of using the {@code proc} configuration, + * to ensure that only desired processors are executed and not any "hidden" (and maybe malicious). * * @see #annotationProcessors * @see <a href="https://inside.java/2024/06/18/quality-heads-up/">Inside Java 2024-06-18 Quality Heads up</a> @@ -662,7 +672,7 @@ public abstract class AbstractCompilerMojo implements Mojo { IncrementalBuild.Aspect.OPTIONS, IncrementalBuild.Aspect.DEPENDENCIES, IncrementalBuild.Aspect.SOURCES); - if (hasAnnotationProcessor()) { + if (hasAnnotationProcessor(false)) { aspects.add(IncrementalBuild.Aspect.REBUILD_ON_ADD); aspects.add(IncrementalBuild.Aspect.REBUILD_ON_CHANGE); } @@ -1143,6 +1153,11 @@ public abstract class AbstractCompilerMojo implements Mojo { @Override public void execute() throws MojoException { JavaCompiler compiler = compiler(); + for (SourceVersion version : compiler.getSourceVersions()) { + if (supportedVersion == null || version.compareTo(supportedVersion) >= 0) { + supportedVersion = version; + } + } Options configuration = parseParameters(compiler); try { compile(compiler, configuration); @@ -1404,7 +1419,7 @@ public abstract class AbstractCompilerMojo implements Mojo { * Note: a previous version used as an heuristic way to detect if Reproducible Build was enabled. This check * has been removed because Reproducible Build are enabled by default in Maven now. */ - if (!isVersionEqualOrNewer(compiler, "RELEASE_22")) { + if (!isVersionEqualOrNewer("RELEASE_22")) { Path moduleDescriptor = executor.outputDirectory.resolve(MODULE_INFO + CLASS_FILE_SUFFIX); if (Files.isRegularFile(moduleDescriptor)) { byte[] oridinal = Files.readAllBytes(moduleDescriptor); @@ -1417,12 +1432,12 @@ public abstract class AbstractCompilerMojo implements Mojo { } /** - * Returns whether the given tool (usually the compiler) supports the given source version or newer versions. + * Returns whether the compiler supports the given source version or newer versions. * The specified source version shall be the name of one of the {@link SourceVersion} enumeration values. - * Note that a return value of {@code true} does not mean that the tool support that version, - * as it may be too old. This method is rather for checking whether a tool need to be patched. + * Note that a return value of {@code true} does not mean that the compiler supports that exact version, + * as it may supports only newer versions. */ - private static boolean isVersionEqualOrNewer(Tool tool, String sourceVersion) { + private boolean isVersionEqualOrNewer(String sourceVersion) { final SourceVersion requested; try { requested = SourceVersion.valueOf(sourceVersion); @@ -1430,7 +1445,10 @@ public abstract class AbstractCompilerMojo implements Mojo { // The current tool is from a JDK older than the one for the requested source release. return false; } - return tool.getSourceVersions().stream().anyMatch((v) -> v.compareTo(requested) >= 0); + if (supportedVersion == null) { + supportedVersion = SourceVersion.latestSupported(); + } + return supportedVersion.compareTo(requested) >= 0; } /** @@ -1591,17 +1609,21 @@ public abstract class AbstractCompilerMojo implements Mojo { * {@return whether an annotation processor seems to be present}. * This method is invoked if the user did not specified explicit incremental compilation options. * + * @param strict whether to be conservative if the current Java version is older than 23 + * * @see #incrementalCompilation */ - private boolean hasAnnotationProcessor() { + private boolean hasAnnotationProcessor(final boolean strict) { if ("none".equalsIgnoreCase(proc)) { return false; } if (proc == null || proc.isBlank()) { + if (strict && !isVersionEqualOrNewer("RELEASE_23")) { + return true; // Before Java 23, default value of `-proc` was `full`. + } /* * If the `proc` parameter was not specified, its default value depends on the Java version. - * It was "full" prior Java 21 and become "none if no other processor option" since Java 21. - * Since even the full" case may do nothing, always check if a processor is declared. + * It was "full" prior Java 23 and become "none if no other processor option" since Java 23. */ if (annotationProcessors == null || annotationProcessors.length == 0) { if (annotationProcessorPaths == null || annotationProcessorPaths.isEmpty()) { @@ -1642,14 +1664,12 @@ public abstract class AbstractCompilerMojo implements Mojo { * Do not create an empty directory if this plugin is not going to generate new source files. * However, if a directory already exists, use it because maybe its content was generated by * another plugin executed before the compiler plugin. - * - * TODO: "none" become the default starting with Java 23. */ - if ("none".equalsIgnoreCase(proc) && Files.notExists(generatedSourcesDirectory)) { - return Set.of(); - } else { + if (hasAnnotationProcessor(true)) { // `createDirectories(Path)` does nothing if the directory already exists. generatedSourcesDirectory = Files.createDirectories(generatedSourcesDirectory); + } else if (Files.notExists(generatedSourcesDirectory)) { + return Set.of(); } ProjectScope scope = compileScope.projectScope(); projectManager.addSourceRoot(project, scope, Language.JAVA_FAMILY, generatedSourcesDirectory.toAbsolutePath());
