Jo, I get that, but this part: "many developers run mvn package or mvn verify". I thought everyone runs "mvn clean install" :D Joke aside, why are they doing that? I mean, does running `mvn install` (instead of mvn verify) incur some huge overhead? Or are they being told to do so? So what is the explanation to run (n-1)th and not n-th phase?
T On Tue, 4 Aug 2026 at 21:48, Guillaume Nodet <[email protected]> wrote: > > THi all, > > > Following the discussion on whether chained local repositories (à la MWM) > could replace project-local-repo, I wanted to clarify the use cases each > solves. They're complementary, not interchangeable. > > > *What project-local-repo solves* > > project-local-repo was introduced in MNG-7629 to support intra-reactor > partial and resumable builds without requiring mvn install. It is populated > on ProjectSucceeded regardless of the lifecycle goal — mvn package, mvn > verify, anything that produces artifacts. > > > This enables workflows like: > - mvn package then mvn test -pl :child — child finds sibling artifacts > - mvn verify fails at module-C, then mvn verify -rf :module-C — modules A > and B's artifacts (including classifiers like sources.jar, test-jar, > consumer POMs) are available from the previous run > - mvn package -DskipTests then mvn surefire:test -pl :single-module — > resolves dependencies from siblings > > The key detail is that classified/attached artifacts (sources.jar, > test-jar, javadoc.jar, consumer POMs) are only resolvable from > project-local-repo during resume. The target/classes fallback in > ReactorReader only handles plain jars without classifiers. > > What chained local repositories solve > > Chained repos (via maven.repo.local.head / MWM) solve cross-project > SNAPSHOT resolution with branch isolation. They allow different branches to > have isolated install targets, so working on multiple branches (or multiple > related projects) doesn't cause artifact conflicts in ~/.m2/repository. > > This enables workflows like: > - Build maven-resolver SNAPSHOT on branch feature-x, then build maven > against it — without polluting ~/.m2/repository or conflicting with the > main branch > - Multiple git worktrees of the same project, each with its own install > target > > Why one can't replace the other > > Chained repos require mvn install to populate the head repository. They > cannot serve the project-local-repo use case because many developers run > mvn package or mvn verify without install. After mvn package, classified > artifacts are in project-local-repo (populated on ProjectSucceeded) but not > in any local repository. > > Conversely, project-local-repo is scoped to a single reactor — it cannot > resolve artifacts across project boundaries. Chained repos solve this > naturally. > > Regarding #12646 > > The race condition exists because project-local-repo currently lives inside > target/, where maven-clean-plugin deletes it during parallel builds. The > proposed fix (PR #12650) moves it to .mvn/target/project-local-repo — > outside the reach of maven-clean-plugin, while keeping the semantic split > (.mvn/ = config, .mvn/target/ = build output, gitignored). > > This is a minimal, targeted fix. Both mechanisms can coexist — chained > repos for cross-project branch isolation, project-local-repo for > intra-reactor partial builds without install. > > PR: https://github.com/apache/maven/pull/12650 > Issue: https://github.com/apache/maven/issues/12646 > > > > Le mar. 4 août 2026 à 21:26, Maarten Mulders <[email protected]> a > écrit : > > > Hi, > > > > The statement that "the unsolicited install happens [...] to make the > > resume `-r` feature work" is only partially true. The original solution > > to get `mvn -r` to work did /not/ involve installing all artifacts in a > > project-local repo. It was later refactored/rewritten by /other/ people > > to work the way you describe. > > > > Thanks, > > > > Maarten > > > > On August 4, 2026 at 15:07, Tamás Cservenák wrote: > > > Howdy, > > > > > > I would just reflect on a funny fact (for me at least): > > > > > > This whole problem (being solved on this thread), stems from one > > > single thing: the unsolicited install that Maven 4 does (cf this to > > > user invoking `mvn install` explicitly). > > > > > > Moreover, this unsolicited install happens, for one thing, to make the > > > resume `-r` feature work. > > > > > > And the true irony is, that this resume feature is backed and > > > advertised by folks, whose mantra is "do not `mvn install` but `mvn > > > verify`" (as install "pollutes' your local repository", whatever that > > > means). > > > > > > That mantra can be now extended with "... as Maven 4 will install it, > > > even if you did not ask for it" :) > > > > > > The more I think about it, the more I find this funny. > > > > > > Thanks > > > T > > > > > > On Tue, 4 Aug 2026 at 14:56, Guillaume Nodet<[email protected]> wrote: > > >> I like the .mvn/target/project-local-repo which solves the problem, > > >> and also provides a good location where plugins could move some > > >> temporary data files without being disturbed by the clean plugin. I'm > > >> thinking about the flatten plugin, the release plugin, and probably > > >> more. > > >> > > >> Le lun. 3 août 2026 à 16:47, Slawomir Jaranowski > > >> <[email protected]> a écrit : > > >>> Hi, > > >>> > > >>> On Mon, 3 Aug 2026 at 14:09, Guillaume Nodet<[email protected]> > > wrote: > > >>>> Hi all, > > >>>> > > >>>> I'd like to get your input on the fix for GH-12646 — a race condition > > 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 the > > >>>> root project and child modules concurrently. Since clean and install > > are > > >>>> placed into the same TaskSegment, there is no barrier between them — > > the > > >>>> root project's maven-clean-plugin can delete target/ while sibling > > modules > > >>>> are concurrently writing artifacts into target/project-local-repo, > > causing > > >>>> 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 — a module could > > >>>> 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 > > IntelliJ > > >>>> stores project caches. This avoids both the race and the git concern, > > but: > > >>>> - Hard links (already used by ReactorReader) cannot cross filesystem > > >>>> boundaries — if ~/.m2/ is on a different volume, every artifact > > becomes 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/, the > > >>>> race becomes structurally impossible. ReactorReader fully owns the > > >>>> lifecycle — 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. > > This > > >>>> 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 — 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=true, since plugin 3.2) > > atomically > > >>>> renames target/ instead of recursively deleting it. This would likely > > avoid > > >>>> the race, but it's opt-in and not the default — 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 the > > >>>> 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 > > document > > >>>> 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 > > >>> > > >>> > > >>> -- > > >>> Sławomir Jaranowski > > >>> > > >>> --------------------------------------------------------------------- > > >>> To unsubscribe, e-mail:[email protected] > > >>> For additional commands, e-mail:[email protected] > > >>> > > >> > > >> -- > > >> ------------------------ > > >> Guillaume Nodet > > >> > > >> --------------------------------------------------------------------- > > >> To unsubscribe, e-mail:[email protected] > > >> For additional commands, e-mail:[email protected] > > >> > > > --------------------------------------------------------------------- > > > To unsubscribe, e-mail:[email protected] > > > For additional commands, e-mail:[email protected] > > > > > > > -- > ------------------------ > Guillaume Nodet --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
