Re: [DISCUSS] Fix for #12646 — moving project-loca l-repo out of target/
Slawomir Jaranowski <[email protected]> Mon, 3 Aug 2026 16:46:59 +0200
| Newsgroups | gmane.comp.jakarta.turbine.maven.devel |
|---|---|
| Message-ID | <CAGjJkv3SE3FRkJENgbYfp4hmog9iOkxQXFe5m3KcN8YhbrytAQ@mail.gmail.com> |
Hi, On Mon, 3 Aug 2026 at 14:09, Guillaume Nodet <[email protected]> wrot= e: > > Hi all, > > I'd like to get your input on the fix for GH-12646 =E2=80=94 a race condi= tion with > project-local-repo during parallel clean install builds. > > The problem > > When the root pom.xml has a parent that is also part of the reactor (e.g.= a > super-pom), MultiThreadedBuilder schedules the parent first, then runs th= e > root project and child modules concurrently. Since clean and install are > placed into the same TaskSegment, there is no barrier between them =E2=80= =94 the > root project's maven-clean-plugin can delete target/ while sibling module= s > are concurrently writing artifacts into target/project-local-repo, causin= g > the build to fail. > > Approaches considered > > 1. Lock-based synchronization (ReentrantReadWriteLock in ReactorReader) > > Acquire a write lock when the project owning target/ enters its clean > phase, and a read lock when installing artifacts. This prevents the crash > (concurrent access) but does not guarantee ordering =E2=80=94 a module co= uld > install artifacts before the root's clean starts, only to have them wiped= . > It also adds complexity to ReactorReader for what is fundamentally an > architectural problem. > > 2. Move project-local-repo to ~/.m2/ (user home) > > E.g. ~/.m2/local-repository/${projectName}_${hash}, similar to how Intell= iJ > stores project caches. This avoids both the race and the git concern, but= : > - Hard links (already used by ReactorReader) cannot cross filesystem > boundaries =E2=80=94 if ~/.m2/ is on a different volume, every artifact b= ecomes a > full copy > - Stale directories accumulate when projects are deleted/moved, with no > cleanup mechanism > - CI containers often share ~/.m2/ across builds, causing unwanted > accumulation > - Loses project locality (harder to inspect/debug) > > 3. Move project-local-repo to .mvn/project-local-repo (chosen) > > Move the directory from target/project-local-repo to > .mvn/project-local-repo. Since maven-clean-plugin only deletes target/, t= he > race becomes structurally impossible. ReactorReader fully owns the > lifecycle =E2=80=94 per-GAV cleanup when a project enters its clean phase= , install > on project success. The existing hard-link optimization continues to work > since both directories are on the same filesystem. > > The trade-off is that .mvn/project-local-repo needs to be gitignored. Thi= s > follows the Gradle convention where .gradle/ at the project root is > universally in .gitignore templates. Maven could also document this > convention or consider auto-appending the entry. > > The fix itself is minimal =E2=80=94 the core change is a single line in > getProjectLocalRepo(), and the rest is removing the lock infrastructure > (net -40 lines). > > 4. Keep in target/ but use maven-clean-plugin fast mode > > The fast clean option (maven.clean.fast=3Dtrue, since plugin 3.2) atomica= lly > renames target/ instead of recursively deleting it. This would likely avo= id > the race, but it's opt-in and not the default =E2=80=94 users hitting the= bug would > need to know about it. > > FWIW, a PR has been raised on m-clean-p master branch (4.x) to refactor t= he > fast cleaner (fixing problems) and make it the default. > > Open questions > > - Is .mvn/ the right location, or should we consider a different > project-root directory? maybe .mvn/target/project-local-repo it should be ignored by git > - Should Maven auto-add .mvn/project-local-repo to .gitignore, or documen= t > it as a convention? > - Are there other considerations I'm missing? > > PR: https://github.com/apache/maven/pull/12650 > Issue: https://github.com/apache/maven/issues/12646 > > Looking forward to your thoughts. > > Cheers > Guillaume Nodet --=20 S=C5=82awomir Jaranowski