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

   ## Proposal: move `project-local-repo` from `target/` to `.mvn/`
   
   ### Root cause
   
   The race condition happens because `project-local-repo` lives inside the 
root project's `target/` directory. During parallel `clean install`, there is 
no ordering guarantee between the root project's clean phase (which deletes 
`target/`) and sibling modules completing their build (which write artifacts 
into `target/project-local-repo`). Since `clean` and `install` are in the same 
`TaskSegment`, they execute concurrently across projects — the root's 
`maven-clean-plugin` and the modules' install can race.
   
   A lock-based approach (e.g. `ReadWriteLock` in `ReactorReader`) prevents the 
crash but does **not** guarantee ordering — a module could install artifacts 
*before* the root's clean runs, only to have them wiped.
   
   ### Proposal
   
   Move `project-local-repo` from `target/project-local-repo` to 
`.mvn/project-local-repo`.
   
   This eliminates the race entirely: `maven-clean-plugin` deletes `target/`, 
but never touches `.mvn/`. The lifecycle of `project-local-repo` is then fully 
owned by `ReactorReader`, which already has `cleanProjectLocalRepository()` — 
it just needs to wipe the whole directory at the start of the build (before the 
executor graph runs), rather than doing per-project GAV cleanup during each 
project's clean phase.
   
   ### Precedent
   
   Storing build-related data outside `target/` (surviving `clean`) is an 
established pattern:
   
   - **Maven Build Cache Extension** — stores cache in 
`~/.m2/.cache/maven-build-cache`
   - **Develocity Maven Extension** — local cache in `~/.m2/.develocity/`
   - **Gradle** — `.gradle/` directory at project root stores build metadata, 
universally gitignored
   
   ### Trade-offs
   
   - **Git**: `.mvn/` is typically a tracked directory. Users (or Maven itself) 
would need to add `.mvn/project-local-repo` to `.gitignore`. This follows the 
Gradle convention where `.gradle/` is universally gitignored.
   - **`mvn clean` semantics**: `clean` would no longer wipe 
`project-local-repo` as a side effect. Instead, `ReactorReader` owns the 
cleanup explicitly — which is arguably more correct, since it already owns the 
creation.
   - **Stale artifacts**: Without the implicit clean via `target/` deletion, 
stale artifacts from previous builds could persist. `ReactorReader` should wipe 
the directory at the start of a build session that includes a clean phase.


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