diff --git a/pom.xml b/pom.xml index 75b3e25f6..8927b8137 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ under the License. 17 - 4.0.0-rc-4 + 4.1.0-SNAPSHOT 9.10.1 7.0.0 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 cac92f902..521b861bd 100644 --- a/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java +++ b/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java @@ -73,6 +73,7 @@ import org.apache.maven.api.services.DependencyResolver; import org.apache.maven.api.services.DependencyResolverRequest; import org.apache.maven.api.services.DependencyResolverResult; +import org.apache.maven.api.services.DiagnosticReporter; import org.apache.maven.api.services.MavenException; import org.apache.maven.api.services.MessageBuilder; import org.apache.maven.api.services.MessageBuilderFactory; @@ -942,6 +943,17 @@ final void amendincrementalCompilation(EnumSet aspects, @Inject protected MessageBuilderFactory messageBuilderFactory; + /** + * Service for reporting structured build diagnostics to the build report. + * Compiler warnings and errors are reported through this service so they + * appear with structured keys, source locations, and suggestions in + * {@code mvnlog --diagnostics} and the JSON build report. + * + * @since 4.0.0-beta-5 + */ + @Inject + protected DiagnosticReporter diagnosticReporter; + /** * The logger for reporting information or warnings to the user. * Currently, this is also used for console output. diff --git a/src/main/java/org/apache/maven/plugin/compiler/DiagnosticLogger.java b/src/main/java/org/apache/maven/plugin/compiler/DiagnosticLogger.java index 9bce7a546..625f82206 100644 --- a/src/main/java/org/apache/maven/plugin/compiler/DiagnosticLogger.java +++ b/src/main/java/org/apache/maven/plugin/compiler/DiagnosticLogger.java @@ -30,11 +30,14 @@ import java.util.Optional; import org.apache.maven.api.plugin.Log; +import org.apache.maven.api.services.BuilderProblem; +import org.apache.maven.api.services.DiagnosticReporter; import org.apache.maven.api.services.MessageBuilder; import org.apache.maven.api.services.MessageBuilderFactory; /** - * A Java compiler diagnostic listener which send the messages to the Maven logger. + * A Java compiler diagnostic listener which sends the messages to the Maven logger + * and reports structured {@link BuilderProblem}s to the {@link DiagnosticReporter}. * * @author Martin Desruisseaux */ @@ -49,6 +52,12 @@ final class DiagnosticLogger implements DiagnosticListener { */ private final MessageBuilderFactory messageBuilderFactory; + /** + * The service for reporting structured diagnostics to the build report. + * May be {@code null} if no reporter is available (e.g. Maven 4.0.x). + */ + private final DiagnosticReporter diagnosticReporter; + /** * The locale for compiler message. */ @@ -75,16 +84,24 @@ final class DiagnosticLogger implements DiagnosticListener { private String firstError; /** - * Creates a listener which will send the diagnostics to the given logger. + * Creates a listener which will send the diagnostics to the given logger + * and to the given diagnostic reporter. * * @param logger the logger where to send diagnostics * @param messageBuilderFactory the factory for creating message builders + * @param diagnosticReporter the reporter for structured build diagnostics, or {@code null} * @param locale the locale for compiler message * @param directory the base directory with which to relativize the paths to source files */ - DiagnosticLogger(Log logger, MessageBuilderFactory messageBuilderFactory, Locale locale, Path directory) { + DiagnosticLogger( + Log logger, + MessageBuilderFactory messageBuilderFactory, + DiagnosticReporter diagnosticReporter, + Locale locale, + Path directory) { this.logger = logger; this.messageBuilderFactory = messageBuilderFactory; + this.diagnosticReporter = diagnosticReporter; this.locale = locale; this.directory = directory; codeCount = new LinkedHashMap<>(); @@ -107,6 +124,17 @@ private String relativize(String file) { return file; } + /** + * Maps a {@link Diagnostic.Kind} to a {@link BuilderProblem.Severity}. + */ + private static BuilderProblem.Severity mapSeverity(Diagnostic.Kind kind) { + return switch (kind) { + case ERROR -> BuilderProblem.Severity.ERROR; + case WARNING, MANDATORY_WARNING -> BuilderProblem.Severity.WARNING; + default -> BuilderProblem.Severity.INFO; + }; + } + /** * Invoked when the compiler emitted a warning. * @@ -176,6 +204,40 @@ public void report(Diagnostic diagnostic) { if (code != null) { codeCount.merge(code, 1, (old, initial) -> old + 1); } + // Report structured diagnostic to the build report + reportToBuildReport(diagnostic, message, code); + } + + /** + * Reports a structured {@link BuilderProblem} to the {@link DiagnosticReporter}. + *

+ * Each diagnostic is reported with a per-type key ({@code "compiler:"}) + * so that the build report deduplicates by diagnostic kind. For example, 50 + * unchecked warnings produce a single entry with count=50 in the summary. + * Individual per-file details remain in the build log. + */ + private void reportToBuildReport(Diagnostic diagnostic, String message, String code) { + if (diagnosticReporter == null || code == null) { + return; + } + BuilderProblem.Builder builder = BuilderProblem.builder() + .severity(mapSeverity(diagnostic.getKind())) + .message(message) + .key("compiler:" + code); + // Attach source location from the first occurrence (collector deduplicates by key) + JavaFileObject sourceFile = diagnostic.getSource(); + if (sourceFile != null) { + builder.source(relativize(sourceFile.getName())); + long line = diagnostic.getLineNumber(); + if (line != Diagnostic.NOPOS) { + builder.lineNumber((int) line); + } + long column = diagnostic.getColumnNumber(); + if (column != Diagnostic.NOPOS) { + builder.columnNumber((int) column); + } + } + diagnosticReporter.report(builder.build()); } /** diff --git a/src/main/java/org/apache/maven/plugin/compiler/ToolExecutor.java b/src/main/java/org/apache/maven/plugin/compiler/ToolExecutor.java index 907d32390..bd8bb26b0 100644 --- a/src/main/java/org/apache/maven/plugin/compiler/ToolExecutor.java +++ b/src/main/java/org/apache/maven/plugin/compiler/ToolExecutor.java @@ -225,7 +225,7 @@ protected ToolExecutor(final AbstractCompilerMojo mojo, DiagnosticListener {}; + } + @Provides @Singleton @SuppressWarnings("unused")