Skip to content

Fix JarFile resource leak in JarDetails#18385

Merged
trask merged 5 commits into
open-telemetry:mainfrom
trask:leak
May 4, 2026
Merged

Fix JarFile resource leak in JarDetails#18385
trask merged 5 commits into
open-telemetry:mainfrom
trask:leak

Conversation

@trask

@trask trask commented Apr 28, 2026

Copy link
Copy Markdown
Member

Extracted from #18382.

Tip

For reviewers, the diff looks better with "Hide whitespace"

JarDetails held an open JarFile in a field and never closed it, so each loaded library leaked one file handle for the JVM's lifetime.

Fix: read pom / manifest / sha1 eagerly in forUrl inside a try-with-resources block, then pass the results into the constructor.
JarDetails becomes an immutable data holder and the JarFile is closed before the factory returns.

The EmbeddedJarDetails subclass existed only to override I/O methods and is no longer needed; replaced with overloaded static helpers (getPom, getManifest, computeDigest) — one variant for top-level jars, one for (JarFile, JarEntry) embedded jars.

No behavior change beyond the leak fix.

@trask
trask marked this pull request as ready for review April 28, 2026 23:56
@trask
trask requested a review from a team as a code owner April 28, 2026 23:56
@trask
trask requested a review from Copilot April 29, 2026 00:00

Copilot AI 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.

Pull request overview

Fixes a file-handle leak in runtime-telemetry’s jar metadata extraction by ensuring JarFile instances are always closed and by turning JarDetails into an immutable data holder.

Changes:

  • Close JarFile via try-with-resources in JarDetails.forUrl() and eagerly compute pom/manifest/sha1 before returning.
  • Remove the EmbeddedJarDetails subclass and replace it with static helper overloads for top-level vs embedded jars.
  • Refactor digest computation helpers to operate on URL/(JarFile, JarEntry) streams instead of holding an open JarFile field.

Comment on lines +79 to +80
urlString.substring(
"jar:file:".length(), index + 1 + entry.getValue().length()))) {

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.

This won't work for paths with spaces since in url space is encoded with %20. For ideas see https://github.com/spring-projects/spring-framework/blob/3184eb3acc8e2e6e95623c43e979ef6c256887ed/spring-core/src/main/java/org/springframework/util/ResourceUtils.java#L324
This can be annoyingly complicated since the urls can be malformed. For example as far as I remember websphere by default doesn't encode spaces to %20.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added support for spaces (and a test)

}
}
return new JarDetails(url, new JarFile(url.getFile()));
try (JarFile jarFile = new JarFile(url.getFile())) {

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.


static JarDetails forUrl(URL url) throws IOException {
if (url.getProtocol().equals("jar")) {
String urlString = url.toExternalForm();

@laurit laurit Apr 29, 2026

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.

Tests don't seem to hit this block. Is this for handling nested jars like when you have one jar inside another jar?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah, added a test for it

trask added 3 commits April 29, 2026 07:15
JarDetails.forUrl was passing the still-URL-encoded path to new JarFile, so paths containing characters like spaces (encoded as %20) would fail to open. Decode via URI.getSchemeSpecificPart, matching the existing pattern in JarAnalyzer. Extract shared helper UrlPaths.
Adds tests that exercise the jar:file URL branch (nested archive URLs like a jar inside a war), including the path-with-spaces case.
@trask
trask merged commit 2a4fb49 into open-telemetry:main May 4, 2026
93 checks passed
@trask
trask deleted the leak branch May 4, 2026 02:55
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.

4 participants