From 1bb74938a70a7dab15795b5ca30d6a14956219f3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 16 Sep 2026 16:50:11 +0200 Subject: [PATCH 1/2] fix(core): Disable manifest URL caching when reading versions (JAVA-730) ManifestVersionReader was retaining jar-backed inflater state while scanning META-INF/MANIFEST.MF entries. Disable URL caching for those reads and close the stream after parsing. --- CHANGELOG.md | 6 ++ .../internal/ManifestVersionReader.java | 87 ++++++++++--------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7160644a780..67c683f0ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Disable URL caching when reading `META-INF/MANIFEST.MF` files during version detection so that the SDK no longer keeps jar file handles open for the life of the process ([#6124](https://github.com/getsentry/sentry-java/pull/6124) + ## 8.57.0 ### Behavioral Changes diff --git a/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java b/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java index 3a0161b1879..7b5ff019edd 100644 --- a/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java +++ b/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java @@ -4,7 +4,9 @@ import io.sentry.SentryIntegrationPackageStorage; import io.sentry.util.AutoClosableReentrantLock; import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -56,48 +58,55 @@ public void readManifestFiles() { ClassLoader.getSystemClassLoader().getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { try { - final @NotNull Manifest manifest = new Manifest(resources.nextElement().openStream()); - final @Nullable Attributes mainAttributes = manifest.getMainAttributes(); - if (mainAttributes != null) { - final @Nullable String name = mainAttributes.getValue("Sentry-Opentelemetry-SDK-Name"); - final @Nullable String version = mainAttributes.getValue("Implementation-Version"); - final @Nullable String sdkName = mainAttributes.getValue("Sentry-SDK-Name"); - final @Nullable String packageName = mainAttributes.getValue("Sentry-SDK-Package-Name"); + final @NotNull URLConnection connection = resources.nextElement().openConnection(); + connection.setUseCaches(false); + try (final @NotNull InputStream inputStream = connection.getInputStream()) { + final @NotNull Manifest manifest = new Manifest(inputStream); + final @Nullable Attributes mainAttributes = manifest.getMainAttributes(); + if (mainAttributes != null) { + final @Nullable String name = + mainAttributes.getValue("Sentry-Opentelemetry-SDK-Name"); + final @Nullable String version = mainAttributes.getValue("Implementation-Version"); + final @Nullable String sdkName = mainAttributes.getValue("Sentry-SDK-Name"); + final @Nullable String packageName = + mainAttributes.getValue("Sentry-SDK-Package-Name"); - if (name != null && version != null) { - versionInfo.sdkName = name; - versionInfo.sdkVersion = version; - final @Nullable String otelVersion = - mainAttributes.getValue("Sentry-Opentelemetry-Version-Name"); - if (otelVersion != null) { - SentryIntegrationPackageStorage.getInstance() - .addPackage("maven:io.opentelemetry:opentelemetry-sdk", otelVersion); - SentryIntegrationPackageStorage.getInstance().addIntegration("OpenTelemetry"); + if (name != null && version != null) { + versionInfo.sdkName = name; + versionInfo.sdkVersion = version; + final @Nullable String otelVersion = + mainAttributes.getValue("Sentry-Opentelemetry-Version-Name"); + if (otelVersion != null) { + SentryIntegrationPackageStorage.getInstance() + .addPackage("maven:io.opentelemetry:opentelemetry-sdk", otelVersion); + SentryIntegrationPackageStorage.getInstance().addIntegration("OpenTelemetry"); + } + final @Nullable String otelJavaagentVersion = + mainAttributes.getValue("Sentry-Opentelemetry-Javaagent-Version-Name"); + if (otelJavaagentVersion != null) { + SentryIntegrationPackageStorage.getInstance() + .addPackage( + "maven:io.opentelemetry.javaagent:opentelemetry-javaagent", + otelJavaagentVersion); + SentryIntegrationPackageStorage.getInstance() + .addIntegration("OpenTelemetry-Agent"); + } + if (name.equals("sentry.java.opentelemetry.agentless")) { + SentryIntegrationPackageStorage.getInstance() + .addIntegration("OpenTelemetry-Agentless"); + } + if (name.equals("sentry.java.opentelemetry.agentless-spring")) { + SentryIntegrationPackageStorage.getInstance() + .addIntegration("OpenTelemetry-Agentless-Spring"); + } } - final @Nullable String otelJavaagentVersion = - mainAttributes.getValue("Sentry-Opentelemetry-Javaagent-Version-Name"); - if (otelJavaagentVersion != null) { - SentryIntegrationPackageStorage.getInstance() - .addPackage( - "maven:io.opentelemetry.javaagent:opentelemetry-javaagent", - otelJavaagentVersion); - SentryIntegrationPackageStorage.getInstance().addIntegration("OpenTelemetry-Agent"); - } - if (name.equals("sentry.java.opentelemetry.agentless")) { - SentryIntegrationPackageStorage.getInstance() - .addIntegration("OpenTelemetry-Agentless"); - } - if (name.equals("sentry.java.opentelemetry.agentless-spring")) { - SentryIntegrationPackageStorage.getInstance() - .addIntegration("OpenTelemetry-Agentless-Spring"); - } - } - if (sdkName != null - && version != null - && packageName != null - && sdkName.startsWith("sentry.java")) { - SentryIntegrationPackageStorage.getInstance().addPackage(packageName, version); + if (sdkName != null + && version != null + && packageName != null + && sdkName.startsWith("sentry.java")) { + SentryIntegrationPackageStorage.getInstance().addPackage(packageName, version); + } } } } catch (Exception e) { From add8663942def2f0d5b0daa8be7cfe8888e0aa54 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 17 Sep 2026 15:33:56 +0200 Subject: [PATCH 2/2] Add comment --- .../src/main/java/io/sentry/internal/ManifestVersionReader.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java b/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java index 7b5ff019edd..af8bd903363 100644 --- a/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java +++ b/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java @@ -59,7 +59,9 @@ public void readManifestFiles() { while (resources.hasMoreElements()) { try { final @NotNull URLConnection connection = resources.nextElement().openConnection(); + // Disable caches to avoid leaking jar-backed inflater state. connection.setUseCaches(false); + try (final @NotNull InputStream inputStream = connection.getInputStream()) { final @NotNull Manifest manifest = new Manifest(inputStream); final @Nullable Attributes mainAttributes = manifest.getMainAttributes();