gnodet opened a new issue, #13808:
URL: https://github.com/apache/maven/issues/13808
## Summary
`AbstractMavenLifecycleParticipant.afterProjectsRead()` is the primary hook
used by build extensions (Tycho, Quarkus, build-cache, jgitver, GraalVM
native-build-tools, …) to mutate reactor projects after collection but **before
the topological sort**. The Maven v4 API needs a proper SPI replacement.
## Why a dedicated SPI, not Listener
- Extensions need to be discovered at **startup** before a full `Session`
exists, making `Session.registerListener()` unsuitable.
- Extensions must be able to **abort the build** on error (checked exception
contract). `Listener.onEvent()` exceptions are swallowed.
- Access to the **full reactor list** is required — cross-project dependency
injection (Tycho resolving P2 deps, jgitver propagating versions) cannot work
per-project in isolation.
## Projects are immutable — mutations go through services
`Project` objects in the v4 API are immutable. All mutations
(adding/replacing dependencies, changing versions, etc.) must go through
`ProjectManager` or other services injected into the implementation. The SPI is
therefore a callback hook, not a functional transformer that returns new
objects.
## Proposed SPI in `maven-api-spi`
```java
@Experimental
@Consumer
@ThreadSafe
public interface ReactorTransformer extends SpiService {
/**
* Called after all reactor projects have been read and before the
reactor is sorted for execution.
* Implementations may mutate project state through services such as
ProjectManager.
* Throwing aborts the build.
*
* @param session the build session
* @param projects all reactor projects, in collection order (not yet
topologically sorted)
*/
void transformReactor(@Nonnull Session session, @Nonnull List<Project>
projects)
throws MavenException;
}
```
## Execution point in DefaultMaven
Fires at step 9 in `DefaultMaven.doExecute()`:
- After: `buildGraph()` (first pass, trimmed) + `getProjectMap()` +
`setupWorkspaceReader()`
- Before: `buildGraph()` (second pass, resort after mutations)
The second `buildGraph()` pass at step 10 already exists precisely to pick
up dependency changes made in this hook.
## Also needed: `ProjectManager.addDependencies()`
The current PR (#13647) adds `ProjectManager.setDependencies()` which
**replaces** all dependencies — dangerous, as callers who forget to include
existing deps silently discard them. Should be `addDependencies()`
(append-only) or the Javadoc must carry a prominent warning.
## Relationship to other SPIs
- `PropertyContributor` (already exists) — fires earlier, before session;
covers the `afterSessionStart` use case (nisse/os-detection).
- `ReactorTransformer` — fires at step 9; covers the `afterProjectsRead` use
case.
- Graph SPI (#13463) — fires at step 6/10; covers reactor graph structure
and topological ordering.
These are sequential and non-overlapping.
## Related
- #13514 — original lifecycle participation issue (PR #13647 implements this)
- #13807 — ProjectExecutionListener for before/after project execution
callbacks
- #13805 — Listener auto-discovery as SpiService
- #13463 — reactor graph SPI
- #13499 — Tycho analysis of v4 SPI gaps
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]