Skip to content

fix: Prevent stale JAR cache in ReflectionsClassFinder under Gradle daemon#23859

Merged
mcollovati merged 1 commit intomainfrom
issue/15458-gradle_plugin_scan_jars_issue
Mar 24, 2026
Merged

fix: Prevent stale JAR cache in ReflectionsClassFinder under Gradle daemon#23859
mcollovati merged 1 commit intomainfrom
issue/15458-gradle_plugin_scan_jars_issue

Conversation

@mcollovati
Copy link
Collaborator

Close URLClassLoader on cleanup to release JAR file handles, and disable JVM-level JAR caching in getResource() by wrapping jar: URLs with a URLStreamHandler that sets useCaches(false).

The Gradle daemon reuses JVMs across builds. When a sibling module's JAR is rewritten, two independent caching layers can hold stale file handles:

  1. URLClassLoader internal cache (URLClassPathJarLoader)
  2. JarFileFactory static HashMap (populated via JarURLConnection)

The URLClassLoader.close() call addresses layer 1, but layer 2 is JVM-global and independent of the class loader. Setting useCaches(false) on jar: URL connections prevents JarFileFactory from caching JarFile instances, matching the approach used by Spring's PathMatchingResourcePatternResolver (SPR-4639).

Fixes #15458

caalador
caalador previously approved these changes Mar 13, 2026
@github-actions
Copy link

github-actions bot commented Mar 13, 2026

Test Results

 1 386 files  ±0   1 386 suites  ±0   1h 28m 26s ⏱️ - 1m 52s
 9 912 tests +1   9 841 ✅ +1  71 💤 ±0  0 ❌ ±0 
10 385 runs  +1  10 305 ✅ +1  80 💤 ±0  0 ❌ ±0 

Results for commit 73c98d5. ± Comparison against base commit 61f2dce.

♻️ This comment has been updated with latest results.

… daemon

Close `URLClassLoader` on cleanup to release JAR file handles, and
disable JVM-level JAR caching in `getResource()` by wrapping `jar:` URLs
with a `URLStreamHandler` that sets `useCaches(false)`.

The Gradle daemon reuses JVMs across builds. When a sibling module's JAR
is rewritten, two independent caching layers can hold stale file handles:
1. `URLClassLoader` internal cache (`URLClassPath` → `JarLoader`)
2. `JarFileFactory` static HashMap (populated via `JarURLConnection`)

The `URLClassLoader.close()` call addresses layer 1, but layer 2 is
JVM-global and independent of the class loader. Setting
`useCaches(false)` on `jar:` URL connections prevents `JarFileFactory`
from caching `JarFile` instances, matching the approach used by Spring's
`PathMatchingResourcePatternResolver` (SPR-4639).

Fixes #15458
@mcollovati mcollovati force-pushed the issue/15458-gradle_plugin_scan_jars_issue branch from 68cc571 to 73c98d5 Compare March 23, 2026 14:28
@sonarqubecloud
Copy link

@mcollovati mcollovati requested a review from caalador March 23, 2026 15:04
@mcollovati mcollovati merged commit b020fac into main Mar 24, 2026
32 checks passed
@mcollovati mcollovati deleted the issue/15458-gradle_plugin_scan_jars_issue branch March 24, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vaadinBuildFrontend irregularly failing with ZipException: ZipFile invalid LOC header (bad signature)

2 participants