Skip to content

Close URLClassLoader in ArchitectureCheck#50626

Merged
snicoll merged 1 commit into
spring-projects:3.5.xfrom
SebTardif:fix/architecture-check-classloader-leak
May 30, 2026
Merged

Close URLClassLoader in ArchitectureCheck#50626
snicoll merged 1 commit into
spring-projects:3.5.xfrom
SebTardif:fix/architecture-check-classloader-leak

Conversation

@SebTardif

Copy link
Copy Markdown
Contributor

URLClassLoader implements Closeable but was never closed in
withCompileClasspath(), leaking JAR file handles in long-running
Gradle daemon processes.

The fix declares the classloader before the try block and closes it
in the finally block after restoring the original context classloader.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 29, 2026
try {
List<URL> urls = new ArrayList<>();
for (File file : getCompileClasspath().getFiles()) {
urls.add(file.toURI().toURL());
}
ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[0]), getClass().getClassLoader());
classLoader = new URLClassLoader(urls.toArray(new URL[0]), getClass().getClassLoader());

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.

I think you can use try-with-resources to make it a little bit better.

try (URLClassLoader classLoader = new URLClassLoader(...)) {
	Thread.currentThread().setContextClassLoader(classLoader);
	callable.call();
}
finally {
	Thread.currentThread().setContextClassLoader(previous);
}

@nosan

nosan commented May 29, 2026

Copy link
Copy Markdown
Contributor

I think your target branch should be 3.5.x, not main, since all branches are affected.

@SebTardif SebTardif force-pushed the fix/architecture-check-classloader-leak branch from c294df5 to 5940265 Compare May 29, 2026 21:39
@SebTardif SebTardif changed the base branch from main to 3.5.x May 29, 2026 21:39
@SebTardif

Copy link
Copy Markdown
Contributor Author

Thanks @nosan for the review!

  • Retargeted base to 3.5.x as suggested (the leak affects the build on all lines).
  • Switched to try-with-resources + nested finally for the context ClassLoader restore (ensures close happens after restore, and close exceptions are properly suppressed rather than masking).

Verified locally:

  • ./gradlew -p buildSrc formatMain checkstyleMain
  • :spring-boot-project:spring-boot:checkArchitectureMainJava (exercises the method) ✅
  • DCO clean.

The updated commit is on the branch.

@snicoll snicoll force-pushed the fix/architecture-check-classloader-leak branch from 5940265 to e699659 Compare May 30, 2026 14:34
See spring-projectsgh-50626

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
@snicoll snicoll force-pushed the fix/architecture-check-classloader-leak branch from e699659 to 6d9fd88 Compare May 30, 2026 14:34
@snicoll snicoll self-assigned this May 30, 2026
@snicoll snicoll added type: task A general task and removed status: waiting-for-triage An issue we've not yet triaged labels May 30, 2026
@snicoll snicoll added this to the 3.5.15 milestone May 30, 2026
@snicoll snicoll merged commit 3cafe9b into spring-projects:3.5.x May 30, 2026
4 checks passed
@snicoll

snicoll commented May 30, 2026

Copy link
Copy Markdown
Member

Thanks @nosan, I had the same thoughts when I had a quick look but I meant to polish in that direction. Thanks @SebTardif for following up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: task A general task

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants