gnodet commented on issue #12586:
URL: https://github.com/apache/maven/issues/12586#issuecomment-5437590397

   > :robot: **Note:** This analysis was generated by a coding agent and 
requires manual verification. The hypotheses and suggestions below should be 
reviewed by a human before taking action.
   
   ## Analysis
   
   After deep investigation of the codebase, this appears to be **intentional 
design**, not a bug.
   
   The concurrent executor and the default executor use fundamentally different 
architectures:
   
   | Aspect | Default/Multithreaded Path | Concurrent Path |
   |---|---|---|
   | Concurrency unit | Entire projects | Individual lifecycle phases |
   | Scheduling | Project-level DAG | Phase-level DAG (`BuildPlan`) |
   | Intra-project concurrency | Never | Yes — by design |
   | Safety mechanism | Runtime locks (`ProjectLock`) | Compile-time ordering 
(DAG edges) |
   
   The Maven 4 lifecycle is a **DAG, not a linear chain**. Independent phases 
like `SOURCES` and `RESOURCES` are deliberate parallel siblings with no 
ordering edge between them:
   
   ```
   BUILD
     SOURCES                    --|  parallel siblings
     RESOURCES                  --|  (no ordering constraint)
     COMPILE (after SOURCES)
     READY (after COMPILE, after RESOURCES)   ← join point
   ```
   
   The `BuildPlanExecutor` only schedules a step when **all its predecessors 
have completed** (via `AtomicInteger` CAS in `BuildStep.status`). Enabling the 
per-project lock would serialize these parallel siblings, destroying the 
concurrent executor's core feature.
   
   ### Direct evidence from the codebase
   
   **1. Code comment in `DefaultLifecycleRegistry.addPhases()`** — when 
computing a flat phase list for v3-compatible display:
   > *"We add ordering between internal phases. This would be wrong at 
execution time, but we are here computing a list and not a graph."*
   
   **2. Test Javadoc in `BuildPlanCreatorTest.testAfterLinkProjectOrdering()`:**
   > *"This is a real constraint: in the V4 lifecycle, 'compile' and 
'resources' are parallel siblings (compile depends on sources, not resources), 
so the @After link creates a genuine ordering edge that doesn't exist 
naturally."*
   
   **3. Fork handling is structural** — `computeForkPlan()` injects DAG nodes 
with proper ordering at plan time. By the time `MojoExecutor.doExecute()` runs, 
`forkedExecutions` is empty.
   
   **4. Aggregation is plan-level** — aggregating goals get their own 
`TaskSegment` with only the root project, making the aggregator lock 
unnecessary.
   
   ### Conclusion
   
   The DAG-based scheduling in `BuildPlanExecutor` subsumes the purpose of the 
per-project lock. Multiple mojos *can* run concurrently on the same project, 
but only when they belong to independent phases with no ordering constraint. 
Phases that share state are connected via `after()` edges and execute 
sequentially. Plugins needing additional ordering can declare `@After` 
annotations.
   
   Closing as works-as-designed.


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