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]
