Spring Boot 4.2.0-SNAPSHOT repeatedly constructs and parses a nested URL in the optimized missing-entry path even when the corresponding nested JarFile is already cached.
In JarUrlConnection.open(URL), a cached nested-JAR lookup currently:
- creates a substring for the nested JAR URL;
- constructs and parses a
URL;
- creates a
JarFileUrlKey for the cache lookup;
- creates a second key for
putIfAbsent.
The URL and second key are unnecessary on a cache hit. This is particularly visible when frameworks probe for optional classes or package-info metadata across a large executable JAR.
Controlled benchmark
I benchmarked the exact path against current main at cf5f3b9ea6 using JDK 26 and a 168 MB real application executable JAR. The JMH benchmark prepares 1,024 distinct missing-resource URLs in the same cached nested spring-core JAR and calls URL.openConnection().
Each of ten external pairs alternated baseline/patched order. Every variant ran in a fresh JVM with one fork, two 1-second warmups, four 1-second measurements, -Xms512m -Xmx512m, and the GC profiler.
| Variant |
Average time |
Allocation |
| Baseline |
283.824 ns/op |
615.221 B/op |
| Direct cached key |
145.676 ns/op |
279.220 B/op |
| Change |
-48.67% |
-54.61% |
All ten pairs favored the change. The paired improvement was 138.148 ns/op with a 99.9% confidence interval of ±25.082 ns/op.
Application JFR confirmation
I also replaced only the affected loader classes in the same application JAR and captured random-port startup JFR recordings with identical settings.
Sample-weighted direct allocation on the targeted path fell from 1,032,112,976 to 204,539,976 bytes (-80.18%). Execution samples whose first frame was a URL constructor fell from 6.10% to 1.03%. This confirms that the isolated allocations are present in a real application startup and that the change removes them.
Six interleaved full-application wall-clock pairs were too noisy to establish an end-to-end duration change: baseline averaged 14.184 seconds and patched averaged 14.157 seconds, with a paired improvement of 0.027 seconds and a 95% confidence interval of ±1.127 seconds. I am including this explicitly to avoid claiming an application startup-time improvement that the wall-clock sample cannot prove.
Proposed change
Create the equivalent JarFileUrlKey directly from the already parsed nested URL specification. Construct and retain a URL only on a cache miss. This preserves the existing key equality rules, including the runtime reference, as well as cold-cache and concurrent-miss behavior.
The loader check passes with 551 tests, zero failures, and three skipped, including new coverage for:
- direct-key and URL-key equality;
- runtime-reference isolation;
- warm and cold cache behavior;
- deterministic concurrent cache misses;
- existing nested and non-nested connection behavior.
This does not change NestedJarFile.hasEntry or its locking behavior discussed in #51379. It also retains the DNS-safe JarFileUrlKey semantics introduced for #46015 and #46401.
Spring Boot 4.2.0-SNAPSHOT repeatedly constructs and parses a nested
URLin the optimized missing-entry path even when the corresponding nestedJarFileis already cached.In
JarUrlConnection.open(URL), a cached nested-JAR lookup currently:URL;JarFileUrlKeyfor the cache lookup;putIfAbsent.The URL and second key are unnecessary on a cache hit. This is particularly visible when frameworks probe for optional classes or
package-infometadata across a large executable JAR.Controlled benchmark
I benchmarked the exact path against current
mainatcf5f3b9ea6using JDK 26 and a 168 MB real application executable JAR. The JMH benchmark prepares 1,024 distinct missing-resource URLs in the same cached nestedspring-coreJAR and callsURL.openConnection().Each of ten external pairs alternated baseline/patched order. Every variant ran in a fresh JVM with one fork, two 1-second warmups, four 1-second measurements,
-Xms512m -Xmx512m, and the GC profiler.All ten pairs favored the change. The paired improvement was 138.148 ns/op with a 99.9% confidence interval of ±25.082 ns/op.
Application JFR confirmation
I also replaced only the affected loader classes in the same application JAR and captured random-port startup JFR recordings with identical settings.
Sample-weighted direct allocation on the targeted path fell from 1,032,112,976 to 204,539,976 bytes (-80.18%). Execution samples whose first frame was a
URLconstructor fell from 6.10% to 1.03%. This confirms that the isolated allocations are present in a real application startup and that the change removes them.Six interleaved full-application wall-clock pairs were too noisy to establish an end-to-end duration change: baseline averaged 14.184 seconds and patched averaged 14.157 seconds, with a paired improvement of 0.027 seconds and a 95% confidence interval of ±1.127 seconds. I am including this explicitly to avoid claiming an application startup-time improvement that the wall-clock sample cannot prove.
Proposed change
Create the equivalent
JarFileUrlKeydirectly from the already parsed nested URL specification. Construct and retain aURLonly on a cache miss. This preserves the existing key equality rules, including theruntimereference, as well as cold-cache and concurrent-miss behavior.The loader check passes with 551 tests, zero failures, and three skipped, including new coverage for:
This does not change
NestedJarFile.hasEntryor its locking behavior discussed in #51379. It also retains the DNS-safeJarFileUrlKeysemantics introduced for #46015 and #46401.