gnodet opened a new issue, #13529:
URL: https://github.com/apache/maven/issues/13529

   ## Summary
   
   When using `--builder concurrent`, specifying multiple lifecycle phases from 
the same lifecycle (e.g., `mvn package install` or `mvn package 
javadoc:aggregate-jar install`) causes later non-overlapping phases to be 
silently dropped. The `install` phase never executes.
   
   ## Steps to reproduce
   
   Create a multi-module project:
   
   ```
   parent (pom)
   ├── module-a (jar)
   └── module-b (jar, depends on module-a)
   ```
   
   Run with the concurrent builder:
   
   ```bash
   # Works correctly - install runs for all modules
   mvn -B --builder concurrent install
   
   # BUG: install phase is silently dropped
   mvn -B --builder concurrent package install
   
   # BUG: install phase is silently dropped
   mvn -B --builder concurrent package javadoc:aggregate-jar install
   ```
   
   ## Expected behavior
   
   `mvn --builder concurrent package install` should run all phases from 
`validate` through `install` (deduplicated), including the `install` phase 
itself.
   
   ## Actual behavior
   
   Only phases up to `package` execute. The `install` phase (and any phases 
between `package` and `install` like `verify`) are silently dropped.
   
   ## Analysis
   
   The issue is in `BuildPlan.merge(Map<String, BuildStep>, Map<String, 
BuildStep>)` at line 98-109 of `BuildPlan.java`.
   
   When merging two plans with overlapping phases:
   1. The merge finds "first" steps in the new plan (steps with no 
predecessors) and chains them after the "last" steps in the existing plan
   2. But only first steps that are **not already present** in the existing 
plan get these ordering edges (line 105: `filter(addNode -> 
!org.containsKey(addNode.name))`)
   3. For `package install`: the new plan's first step (e.g., `validate`) 
already exists in the existing plan, so it gets filtered out
   4. The truly new steps (`verify`, `install`) are NOT first steps — they have 
predecessors within their own plan
   5. Result: the new steps get added to the map but have no ordering edges 
connecting them to the existing plan's terminal steps
   
   The overlapping phases get correctly merged via `putIfAbsent`, but the 
non-overlapping later phases become unreachable in the execution graph.
   
   ## Comparison with sequential/multithreaded builders
   
   The sequential and multithreaded builders (`-T N`) process each task segment 
independently and re-run all phases from scratch. They never lose phases but 
duplicate execution (e.g., `mvn package install` runs `validate`→`package` 
twice).
   
   | Command | Sequential / `-T` | `--builder concurrent` |
   |---|---|---|
   | `install` | validate→install × 1 | validate→install × 1 ✅ |
   | `package install` | validate→package × 2, then install | validate→package 
× 1, **install lost** ❌ |
   | `package javadoc:aggregate-jar install` | validate→package × 3, then 
install | validate→package × 1, javadoc, **install lost** ❌ |
   
   _Claude Code on behalf of Guillaume Nodet_


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