Re: [DISCUSS] Incremental Build Context API for Maven 4.1.0 (PR #12576)

Romain Manni-Bucau <[email protected]>
Newsgroups gmane.comp.jakarta.turbine.maven.devel
Message-ID <CACLE=7MK6VSHLRG4BQpyyG7EoYkD6CnjnjCGb-KNSGe765EhTg@mail.gmail.com>
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
> > >
> >
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.