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
> > >
> >
>

Reply via email to