Create the local repository directory before resolving its real path - #2111
Conversation
Since apache#2104 the enhanced local repository manager resolves the real path of its base directory eagerly, in the constructor. Path.toRealPath() requires the path to exist, so a local repository that has not been created yet (first build on a machine, a new -Dmaven.repo.local) made the factory fail with NoLocalRepositoryManagerException. The provider treats that as "try the next factory" and quietly fell back to the simple manager, so the whole first session ran without the tracking file. Before apache#2104 the real path was computed lazily, only for files that already existed, so the directory was always there. Create the directory first. Maven creates it on first write anyway, and the enhanced manager needs it for its tracking files, so the side effect changes nothing observable for a usable local repository.
gnodet
left a comment
There was a problem hiding this comment.
Clean, minimal regression fix. PR #2104 moved toRealPath() from lazy to eager evaluation in the EnhancedLocalRepositoryManager constructor, but toRealPath() requires the directory to exist. When the local repository has not been created yet (first build, or a new -Dmaven.repo.local), the constructor threw IOException, causing silent fallback to SimpleLocalRepositoryManager. The fix — a single Files.createDirectories() call before toRealPath() — is correct, idempotent, and safe for concurrent use.
The two tests are well-designed: newInstanceForNotYetExistingBasedir verifies the factory layer, while providerSelectsEnhancedManagerForNotYetExistingBasedir tests the complete fallback chain through DefaultLocalRepositoryProvider. Both fail on origin/master without the fix.
📋 PR Metadata
| Aspect | Current | Suggested |
|---|---|---|
| Category | (unlabeled) | bug |
| Labels | (none) | + bug |
| Milestone | (none) | 2.0.23 |
🔀 Backport Status
✅ Not needed — the regression source (PR #2104) was only merged to master and is not present on either maintenance branch (maven-resolver-1.9.x, maven-resolver-1.6.x).
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Since #2104
EnhancedLocalRepositoryManagerresolves the real path of its base directory in the constructor, andPath.toRealPath()requires the path to exist.A local repository that has not been created yet (first build on a machine, or a new
-Dmaven.repo.local) therefore made the enhanced factory throwNoLocalRepositoryManagerException.DefaultLocalRepositoryProvidertreats that as "try the next factory" and quietly selectedSimpleLocalRepositoryManager, so the whole first session ran without_remote.repositoriestracking. Before #2104 the real path was computed lazily, only for files that already existed, so the directory was always present.The fix creates the directory before resolving it. Maven creates it on first write anyway and the enhanced manager needs it for its tracking files, so nothing observable changes for a usable local repository; an unwritable location still fails the same way it did before.
Two tests cover the factory directly and the provider's fallback selection with a not-yet-existing base directory; both fail on master with the
NoSuchFileExceptioncause.This change was created with AI assistance.