looks good to me, might be worth testing making processors happy without a full rebuild (=making them stateful) but this is a great first version bringing already a lot
Romain Manni-Bucau @rmannibucau <https://x.com/rmannibucau> | .NET Blog <https://dotnetbirdie.github.io/> | Blog <https://rmannibucau.github.io/> | Old Blog <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book <https://www.packtpub.com/en-us/product/java-ee-8-high-performance-9781788473064> Javaccino <https://javaccino.dev/> founder (Java/.NET service - contact via linkedin) Le dim. 9 août 2026 à 10:16, Guillaume Nodet <[email protected]> a écrit : > Hi Romain, > > I've pushed updates to the PR and companion plugins addressing the > feedback. Here's the summary: > > Naming > > Renamed across the board per the discussion: > - Package: o.a.m.api.build.context → o.a.m.api.build.incremental > - Interface: BuildContext → IncrementalContext > - SPI: CommittableBuildContext → CommittableIncrementalContext > - Impl: DefaultBuildContext → DefaultIncrementalContext > > The user-facing skip property stays maven.buildcontext.skip for now — it > can always be updated later, and recognition matters more than consistency > there. > > MojoConfigurationDigester — XML tree hashing > > Rewrote the digester to walk the XML configuration tree from > MojoExecution.getConfiguration() instead of reflecting over field values. > For each element, it feeds the element name, attributes (minus > default-value), and the expression-evaluated text value into a SHA-1 > digest. Expressions like ${project.build.directory} are resolved through > the ExpressionEvaluator, so -D property overrides are properly detected. > Nested elements are handled recursively. > > Reflection is only used to read @Incremental annotations on the mojo class > (cached per class) — field values are never accessed via reflection. This > means the digester works correctly with any parameter type, including > collections, maps, and custom objects, without needing type-specific > serialization logic. > > @Incremental(consider=false) is preserved — annotating a mojo field > excludes that parameter from change detection. The annotation targets > FIELD, METHOD, PARAMETER, and TYPE, with RUNTIME retention, so it's > available to the digester at execution time. > > Companion plugin updates > > All four companion plugins have been updated for the rename: > - maven-filtering (#363) > - maven-resources-plugin (#496) > - maven-jar-plugin (#566) > - maven-compiler-plugin (#1096) > > Incremental annotation processor scanning (compiler plugin) > > While updating the compiler plugin, I also added support for incremental > annotation processing. The compiler plugin now scans processor JARs for > incrementality descriptors before deciding whether to force a full rebuild: > > - Reads META-INF/maven/incremental.annotation.processors (Maven-specific, > takes precedence) > - Falls back to META-INF/gradle/incremental.annotation.processors (Gradle's > established convention — Dagger, AutoValue, MapStruct, etc. already ship > these) > - Cross-references with > META-INF/services/javax.annotation.processing.Processor — any > ServiceLoader-declared processor without a descriptor entry triggers > conservative behavior > > Format is one line per processor: com.example.MyProcessor,isolating > > The aggregate logic: if all processors declare isolating, per-file > incremental compilation is preserved (no REBUILD_ON_ADD / > REBUILD_ON_CHANGE). If any is aggregating, the full set of annotated > sources is reprocessed on any change. dynamic or undeclared processors fall > back to the current full-rebuild-on-change behavior. > > This doesn't require any API change — the IncrementalContext already has > the right primitives (Input.associateOutput() for isolating, > InputSet.aggregate() for aggregating). The descriptor format and scanning > logic lives entirely in the compiler plugin. > > The PRs are all draft — happy to iterate on any of this. > > ------------------------ > Guillaume Nodet > > > Le lun. 3 août 2026 à 16:36, Romain Manni-Bucau <[email protected]> a > écrit : > > > Hi, > > > > Sounds a very good move, my 2 cts would be > > > > 1. while it ends in the new API it is great > > 2. why reflection since descriptor is in mem at some point? +1 to be able > > to tune it with a dedicated API > > 3. while documented yes IMHO > > > > side note: how would we make compilation incremental with annot proc? > > dedicated API as gradle? should we lean toward an unified api? > > > > Romain Manni-Bucau > > @rmannibucau <https://x.com/rmannibucau> | .NET Blog > > <https://dotnetbirdie.github.io/> | Blog <https://rmannibucau.github.io/ > > > > | Old > > Blog <http://rmannibucau.wordpress.com> | Github > > <https://github.com/rmannibucau> | LinkedIn > > <https://www.linkedin.com/in/rmannibucau> | Book > > < > > > https://www.packtpub.com/en-us/product/java-ee-8-high-performance-9781788473064 > > > > > Javaccino <https://javaccino.dev/> founder (Java/.NET service - contact > > via > > linkedin) > > > > > > Le lun. 3 août 2026 à 14:14, Guillaume Nodet <[email protected]> a > > écrit : > > > > > Hi all, > > > > > > I'd like to bring up the incremental build context work for discussion. > > > > > > Background > > > > > > This builds on a long lineage: the original plexus-build-api by > Sonatype > > > (Igor Fedorenko), later evolved into Takari's > io.takari.incrementalbuild > > > API, which powered m2e's incremental workspace builds in Eclipse. I > > started > > > porting this to Maven 4 in PR #1118 a while back; PR #12576 picks that > > up, > > > modernizes it to Maven 4 conventions (@MojoExecutionScoped DI, > > > @Experimental annotations, PathMatcherFactory reuse), adds performance > > > optimizations, and integrates it with four core plugins as > > > proof-of-concept. > > > > > > What it provides > > > > > > A first-class API in maven-api-core for mojo authors to track input > file > > > changes, associate inputs with outputs, skip execution when nothing > > > changed, and get automatic stale output cleanup — all things the old > > > plexus-build-api did, but now as part of Maven's public API with an SPI > > > layer for IDE integration (workspace modes for m2e-style delta builds). > > > > > > The framework automatically digests @Parameter fields and the plugin > > > classpath to detect configuration changes — mojos get this for free > > without > > > implementing their own checks. > > > > > > Performance > > > > > > Benchmarked against stock 3.x plugins on a 20-module reactor (4000 > > sources, > > > 600 resources): > > > > > > - No-op rebuild: −44% (15.7s → 8.7s) > > > - Single file change: −40% > > > - Delete + stale cleanup: −48% > > > - Clean build: +39% overhead (amortized after one incremental rebuild) > > > > > > A -Dmaven.buildcontext.skip=true property disables the context entirely > > for > > > CI/release builds. > > > > > > Plugin integrations > > > > > > - maven-resources-plugin#496 + maven-filtering#363 > > > - maven-jar-plugin#566 > > > - maven-compiler-plugin#1096 > > > > > > Questions for discussion > > > > > > 1. Is o.a.m.api.build.context the right package home? (Chosen to avoid > > > collision with build report API in #12572) > > > 2. Automatic @Parameter digestion via reflection — should it be opt-in > > via > > > @Incremental instead? > > > 3. The context is per-mojo-execution, no cross-module coordination. > > > Sufficient for a first iteration? > > > > > > Main PR: https://github.com/apache/maven/pull/12576 > > > Original PR: https://github.com/apache/maven/pull/1118 > > > > > > Feedback welcome. > > > > > > Guillaume > > > > > >
