Emit structured BuilderProblems from maven-compiler-plugin for build report integration
- Dominant language
- Java
- Stars
- 5.3k
- Forks
- 3.1k
- Avg merge
- 20h 42m
- Merged PRs (30d)
- 297
Description
## 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 structured source location from the compiler diagnostic
- No per-warning deduplication control
## API Design — Resolved
The plugin API question was resolved with a new injectable service in Maven 4.1.0:
```java
@Inject DiagnosticReporter diagnosticReporter;
diagnosticReporter.report(BuilderProblem.builder()
.key("compiler:compiler.warn.unchecked:src/main/java/Foo.java:42")
.severity(BuilderProblem.Severity.WARNING)
.message("unchecked cast")
.source("src/main/java/Foo.java")
.lineNumber(42)
.columnNumber(15)
.build());
```
`DiagnosticReporter` is a simple injectable service that pipes `BuilderProblem` objects directly into the `DefaultDiagnosticCollector`.
## Implementation Status
### ✅ Done — maven-compiler-plugin (PR apache/maven-compiler-plugin#1101)
The compiler plugin now maps each `javax.tools.Diagnostic` to a Maven `BuilderProblem` and reports it via `DiagnosticReporter`:
- **Per-location dedup keys**: `compiler:::` — each unique file+line gets its own entry in the build report. 50 unchecked warnings across 50 files produce 50 separate entries (not collapsed into one).
- **Source location**: `source`, `lineNumber`, `columnNumber` from the compiler diagnostic
- **Severity mapping**: `Diagnostic.Kind.ERROR` → `ERROR`, `WARNING`/`MANDATORY_WARNING` → `WARNING`, others → `INFO`
- **Suppression**: Users can suppress via `-Dmaven.diagnostic.suppress=compiler:*` (all) or `compiler:compiler.warn.unchecked` (specific prefix)
- **No behavior change**: Existing logging behavior is unchanged — `DiagnosticReporter` is additive
CI note: PR #1101 expects Maven 4.1.0-SNAPSHOT (for `DiagnosticReporter` API); CI will pass once #12572 is merged and a snapshot is published.
### 🔲 Future — Other high-impact plugins
After the compiler plugin, the same `DiagnosticReporter` pattern can 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
### 🔲 Future — Maven 3 plugin bridge
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:compiler.warn.unchecked:src/main/java/com/example/Service.java:42
source: src/main/java/com/example/Service.java:42:15
[WARN] [deprecation] OldApi.method() has been deprecated
key: compiler:compiler.warn.has.been.deprecated:src/main/java/com/example/Client.java:87
source: src/main/java/com/example/Client.java:87:8
```
## Depends on
- #12572 (Build Report Foundation)
- #12643 (Structured BuilderProblem piping in Maven core)
Contributor guide
Research direction
Start by reviewing PR apache/maven-compiler-plugin#1101 and the dependency issues #12572 and #12643, since the compiler-plugin implementation is marked done and this issue lists only future plugin work. Done would require a specifically scoped remaining target, such as surefire, enforcer, dependency, or javadoc integration, with its relevant entry points and tests identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- build-system
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 15/100