Skip to content

Fix #12604: DefaultSettingsBuilder dead Windows drive-relative path handling - #12631

Merged
elharo merged 1 commit into
masterfrom
fix-12604-settings-path
Jul 30, 2026
Merged

Fix #12604: DefaultSettingsBuilder dead Windows drive-relative path handling#12631
elharo merged 1 commit into
masterfrom
fix-12604-settings-path

Conversation

@elharo

@elharo elharo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #12604

Problem

The condition !file.isAbsolute() && file.toString().startsWith(File.separator) is always false on all platforms:

  • On Unix: any path starting with / is absolute, so !file.isAbsolute() is false
  • On Windows: any path starting with \ is absolute (drive-relative), so !file.isAbsolute() is false

This made the entire local repository path resolution block dead code.

Fix

Replace the impossible condition with !file.isAbsolute() (skipping paths containing ${ placeholders that need later interpolation). This correctly resolves relative paths like relative/repo to absolute.

Testing

Added testRelativeLocalRepositoryIsResolvedToAbsolute which loads a settings file with <localRepository>relative/repo</localRepository> and verifies the output path is absolute.

Existing test testSettingsWithServersAndAliases continues to pass because paths containing ${user.home} placeholders are left untouched.

…andling

Remove the always-false condition !file.isAbsolute() && file.toString().startsWith(File.separator) which is dead code on all platforms - paths starting with the file separator are already absolute.

Replace with !file.isAbsolute() (skipping paths containing ${} placeholders that need later interpolation). This correctly resolves all relative local repository paths to absolute, not just the never-reached Windows-specific case.
@elharo
elharo requested a review from Copilot July 30, 2026 13:49
@elharo elharo added the bug Something isn't working label Jul 30, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Clean, well-scoped fix that replaces an effectively dead condition with a broader relative-path resolution guard. The new contains("${") check follows established Maven conventions (used in 7+ other places in the codebase), the import cleanup is correct, and the test adequately covers both the happy path and the placeholder-preservation case.

Notes:

  • The PR description states the old condition !file.isAbsolute() && file.toString().startsWith(File.separator) is "always false on all platforms." This is accurate for Unix/Mac. On Windows, Path.isAbsolute() returns false for drive-relative paths like \foo, so the old condition could theoretically be true — but the new broader condition is a strict superset and an improvement.
  • The !localRepository.contains("${") guard is consistent with the same pattern used in DefaultDependencyResolver, DefaultModelBuilder, DefaultModelValidator, DefaultArtifactDescriptorReader, and MavenValidator.

Minor (non-blocking): The new test resource settings-relative-local-repo.xml lacks the ASF license header that sibling files have. RAT excludes src/test/resources*/** so it's not enforced, but adding it would be consistent.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes #12604 by making local-repository path normalization effective again, ensuring relative <localRepository> values become absolute while preserving ${...} placeholders for later interpolation.

Changes:

  • Update DefaultSettingsBuilder to resolve non-absolute, non-placeholder local repository paths to absolute.
  • Add a test settings XML using a relative <localRepository>.
  • Add a JUnit test verifying the effective local repository path becomes absolute.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java Replaces dead condition with a relative-path resolution rule while skipping ${...} placeholder paths.
impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsBuilderFactoryTest.java Adds a regression test asserting relative local repository paths are resolved to absolute.
impl/maven-impl/src/test/resources/settings/settings-relative-local-repo.xml Adds a minimal settings fixture defining a relative local repository path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 133 to 139
String localRepository = effective.getLocalRepository();
if (localRepository != null && !localRepository.isEmpty()) {
Path file = Paths.get(localRepository);
if (!file.isAbsolute() && file.toString().startsWith(File.separator)) {
if (!file.isAbsolute() && !localRepository.contains("${")) {
effective = effective.withLocalRepository(file.toAbsolutePath().toString());
}
}
Comment on lines +164 to +173
@Test
void testRelativeLocalRepositoryIsResolvedToAbsolute() {
Settings settings = execute("settings-relative-local-repo").getEffectiveSettings();

String localRepository = settings.getLocalRepository();
assertNotNull(localRepository);
assertFalse(localRepository.isEmpty());
Path repoPath = Paths.get(localRepository);
assertTrue(repoPath.isAbsolute(), "Relative local repository should be resolved to absolute");
}
@elharo
elharo merged commit 0ae0645 into master Jul 30, 2026
24 checks passed
@elharo
elharo deleted the fix-12604-settings-path branch July 30, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[maven-4.0.x] DefaultSettingsBuilder: dead Windows drive-relative path handling

3 participants