Skip to content

Emit structured BuilderProblems from maven-compiler-plugin for build report integration #12644

Description

@gnodet

Context

PR #12572 (Build Report Foundation) introduced a structured problem reporting system using BuilderProblem with key, suggestion, documentationUrl, and severity. Currently, plugin warnings are captured via SLF4J WARN-level log interception, which loses structured metadata.

Plugins should emit structured BuilderProblem objects directly to the build report system, starting with maven-compiler-plugin as the highest-impact target.

Problem

Today, compiler warnings flow through:

javac DiagnosticCollector → compiler plugin Log.warn(text) → SLF4J → BuildReportCollector

This means:

  • Compiler warnings appear as flat text with auto-generated keys
  • No suggestion (e.g. "add @SuppressWarnings" or "use --release instead of -source/-target")
  • No documentationUrl (e.g. link to the specific warning documentation)
  • No structured source location from the compiler diagnostic

Proposed Solution

Phase 1: maven-compiler-plugin

The compiler plugin already uses javax.tools.DiagnosticCollector internally. It should map each javax.tools.Diagnostic to a Maven BuilderProblem:

// Mapping javax.tools.Diagnostic → BuilderProblem
BuilderProblem.builder()
    .key("compiler:" + diagnostic.getCode())           // e.g. "compiler:unchecked"
    .severity(mapKind(diagnostic.getKind()))            // WARNING → WARNING
    .message(diagnostic.getMessage(locale))
    .source(diagnostic.getSource().getName())           // e.g. "src/main/java/Foo.java"
    .line(diagnostic.getLineNumber())
    .column(diagnostic.getColumnNumber())
    .suggestion(suggestFor(diagnostic.getCode()))       // e.g. "Add @SuppressWarnings(\"unchecked\")"
    .documentationUrl(docsFor(diagnostic.getCode()))    // link to javac lint docs
    .build();

The plugin would report these through the Maven 4 plugin API (new method on the build context or session, TBD).

Phase 2: Other high-impact plugins

After the compiler plugin, extend to:

  • maven-surefire-plugin — test failures as structured problems with test class/method
  • maven-enforcer-plugin — rule violations with rule name as key
  • maven-dependency-plugin — unused/undeclared dependency warnings
  • maven-javadoc-plugin — javadoc warnings with source location

API Design Consideration

A new method is needed on the Maven 4 plugin API to let plugins report structured problems:

// Option A: on MojoExecution context
public interface MojoExecutionContext {
    void reportProblem(BuilderProblem problem);
}

// Option B: injectable service
@Inject ProblemReporter problemReporter;
problemReporter.report(BuilderProblem.builder()...build());

This API design should be coordinated with the Maven core team.

Phase 3: Plugin API for Maven 3 plugins

For backward compatibility, Maven 3 plugins that use getLog().warn() already have their warnings captured by the SLF4J hook (implemented in #12572). A bridge could be provided to let Maven 3 plugins opt in to structured reporting without requiring a full Maven 4 API migration.

Expected Outcome

$ mvnlog --diagnostics
Problems (3): 3 warnings

  [WARN]  unchecked cast
          key: compiler:unchecked
          source: src/main/java/com/example/Service.java:42:15
          suggestion: Add @SuppressWarnings("unchecked") or use parameterized types
          docs: https://docs.oracle.com/en/java/javase/21/docs/specs/man/javac.html#xlint

  [WARN]  [deprecation] OldApi.method() has been deprecated
          key: compiler:deprecation
          source: src/main/java/com/example/Client.java:87:8
          suggestion: Use NewApi.method() instead
          docs: https://docs.oracle.com/en/java/javase/21/docs/specs/man/javac.html#xlint

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions