Skip to content

Fix local cache path fallback for Spring Boot 3 executable JARs#136

Open
nobodyiam wants to merge 1 commit intoapolloconfig:mainfrom
nobodyiam:codex/issue-5592-spring-boot3-cache
Open

Fix local cache path fallback for Spring Boot 3 executable JARs#136
nobodyiam wants to merge 1 commit intoapolloconfig:mainfrom
nobodyiam:codex/issue-5592-spring-boot3-cache

Conversation

@nobodyiam
Copy link
Copy Markdown
Member

@nobodyiam nobodyiam commented Apr 7, 2026

What's the purpose of this PR

Fix Apollo Java local cache directory resolution when running from a Spring Boot 3 executable JAR.

ClassLoaderUtil previously assumed that jar-internal classpath locations would contain .jar!, but Spring Boot 3 executable JARs expose nested URLs such as jar:nested:/.../!BOOT-INF/classes/!/. When Apollo falls back to ClassLoaderUtil.getClassPath() for local cache persistence, that nested URL was treated as a filesystem path and config-cache directory creation failed.

Which issue(s) this PR fixes:

Fixes apolloconfig/apollo#5592

Brief changelog

  • Only treat file: resources as filesystem classpath locations and fall back to user.dir for nested-jar URLs.
  • Add regression tests for normal file URL resolution and Spring Boot 3 nested-jar fallback.
  • Validate the affected paths with:
    • mvn -pl apollo-core -Dtest=ClassLoaderUtilTest test -Dmaven.gitcommitid.skip=true
    • mvn -pl apollo-client -am -Dtest=ClassLoaderUtilTest,LocalFileConfigRepositoryTest,DefaultConfigTest -Dsurefire.failIfNoSpecifiedTests=false test -Dmaven.gitcommitid.skip=true

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Read the Contributing Guide before making this pull request.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit tests to verify the code.
  • Run mvn clean test to make sure this pull request doesn't break anything.
  • Update the CHANGES log.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Apollo client local cache fallback behavior for Spring Boot 3 executable JARs.

Copilot AI review requested due to automatic review settings April 7, 2026 14:10
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 582e0f2a-61c4-4d2d-a892-8904f27a3c86

📥 Commits

Reviewing files that changed from the base of the PR and between c89320a and 1055f6b.

📒 Files selected for processing (3)
  • CHANGES.md
  • apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtil.java
  • apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtilTest.java

📝 Walkthrough

Walkthrough

This PR fixes Apollo client's local cache file creation for Spring Boot 3 by refactoring ClassLoaderUtil's classpath detection logic. The new helper method improves URL-to-path conversion using java.nio.file.Paths and adjusts fallback conditions to handle Spring Boot 3 executable JAR changes.

Changes

Cohort / File(s) Summary
Release Notes
CHANGES.md
Added release note documenting the Spring Boot 3 local cache fallback fix.
Classpath Detection
apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtil.java
Extracted classpath resolution into new helper method; improved URL-to-path conversion using Paths.get(url.toURI()).toString() instead of manual decoding; refined fallback logic to handle missing or non-file protocol URLs; removed URLDecoder, added java.nio.file.Paths.
Classpath Detection Tests
apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtilTest.java
Added two tests validating resolveClassPath() behavior with file and JAR URLs; introduced helper methods for custom ClassLoader and URL creation with custom protocol handlers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • Anilople

Poem

🐰 A hop through classpaths, fresh and clean,
Where Spring Boot 3's JAR paths gleamed,
No more .jar! tricks to deceive,
Paths.get() makes caches believe,
Now local files spring to life! 🌱

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing local cache path fallback for Spring Boot 3 executable JARs, which is the primary objective of this PR.
Linked Issues check ✅ Passed The PR successfully addresses issue #5592 by updating ClassLoaderUtil to detect nested-jar URLs and fall back to user.dir, with tests validating both file URL resolution and Spring Boot 3 nested-jar fallback.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing Spring Boot 3 classpath resolution: ClassLoaderUtil refactoring, comprehensive test coverage, and documentation update in CHANGES.md.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nobodyiam nobodyiam force-pushed the codex/issue-5592-spring-boot3-cache branch from 3bbe114 to 1055f6b Compare April 7, 2026 14:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes Apollo Java’s local cache directory resolution when running from Spring Boot 3 executable (nested) JARs by avoiding treating nested-jar classpath URLs as filesystem paths, and instead falling back to a safe default (user.dir).

Changes:

  • Refactors ClassLoaderUtil classpath resolution to only treat file: URLs as filesystem locations and otherwise fall back to a provided default.
  • Adds regression tests covering both file: URL resolution and Spring Boot 3 nested-jar URL fallback behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtil.java Introduces resolveClassPath(...) using URL protocol checks and Paths.get(url.toURI()) to prevent nested-jar URLs from being used as filesystem paths.
apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtilTest.java Adds tests validating correct handling for file: URLs and fallback behavior for nested-jar URLs.

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

Comment on lines +57 to +66
static String resolveClassPath(ClassLoader classLoader, String defaultClassPath) throws Exception {
URL url = classLoader.getResource("");
if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) {
return defaultClassPath;
}

String resolvedClassPath = Paths.get(url.toURI()).toString();
if (Strings.isNullOrEmpty(resolvedClassPath)) {
return defaultClassPath;
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

resolveClassPath now derives the classpath via Paths.get(url.toURI()).toString(), which changes the returned format on Windows (it will no longer include the leading / that URL#getPath() produced). There is existing code in the repo that compensates for the old behavior (e.g. apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java strips the leading /), which will become incorrect with this change and can break Windows builds/tests. Consider either preserving the previous Windows formatting (e.g. keep using the decoded url.getPath() for file: URLs) or updating the affected call sites/tests to stop assuming a leading / from getClassPath().

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

springboot 3 + apollo client无法创建本地缓存文件

2 participants