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]

Reply via email to