diff --git a/CHANGELOG.md b/CHANGELOG.md index da591e6789..595a1455b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Cap max number of stack frames to 100 to not exceed payload size limit ([#3009](https://github.com/getsentry/sentry-java/pull/3009)) - This will ensure we report errors with a big number of frames such as `StackOverflowError` - Fix user interaction tracking not working for Jetpack Compose 1.5+ ([#3010](https://github.com/getsentry/sentry-java/pull/3010)) +- Make sure to close all Closeable resources ([#3000](https://github.com/getsentry/sentry-java/pull/3000) ## 6.32.0 diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java index f3d257d225..19c7eff04f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java @@ -292,26 +292,18 @@ private void reportAsSentryEvent( private @NotNull ParseResult parseThreadDump( final @NotNull ApplicationExitInfo exitInfo, final boolean isBackground) { - InputStream trace; - try { - trace = exitInfo.getTraceInputStream(); + final byte[] dump; + + try (final InputStream trace = exitInfo.getTraceInputStream()) { if (trace == null) { return new ParseResult(ParseResult.Type.NO_DUMP); } + dump = getDumpBytes(trace); } catch (Throwable e) { options.getLogger().log(SentryLevel.WARNING, "Failed to read ANR thread dump", e); return new ParseResult(ParseResult.Type.NO_DUMP); } - byte[] dump = null; - try { - dump = getDumpBytes(trace); - } catch (Throwable e) { - options - .getLogger() - .log(SentryLevel.WARNING, "Failed to convert ANR thread dump to byte array", e); - } - try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(dump)))) { final Lines lines = Lines.readLines(reader); @@ -330,16 +322,17 @@ private void reportAsSentryEvent( } private byte[] getDumpBytes(final @NotNull InputStream trace) throws IOException { - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream()) { - int nRead; - final byte[] data = new byte[1024]; + int nRead; + final byte[] data = new byte[1024]; - while ((nRead = trace.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); - } + while ((nRead = trace.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } - return buffer.toByteArray(); + return buffer.toByteArray(); + } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java index eac29bc42d..4becb0925b 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java @@ -22,6 +22,7 @@ import io.sentry.protocol.User; import io.sentry.util.MapObjectWriter; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -142,10 +143,10 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { final @NotNull IHub hub = HubAdapter.getInstance(); final @NotNull SentryOptions options = hub.getOptions(); - try { + try (final InputStream envelopeInputStream = new ByteArrayInputStream(envelopeData)) { final @NotNull ISerializer serializer = options.getSerializer(); final @Nullable SentryEnvelope envelope = - options.getEnvelopeReader().read(new ByteArrayInputStream(envelopeData)); + options.getEnvelopeReader().read(envelopeInputStream); if (envelope == null) { return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java index c381bacf0a..6d6f3737cb 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java @@ -26,8 +26,7 @@ public AssetsModulesLoader(final @NotNull Context context, final @NotNull ILogge protected Map loadModules() { final Map modules = new TreeMap<>(); - try { - final InputStream stream = context.getAssets().open(EXTERNAL_MODULES_FILENAME); + try (final InputStream stream = context.getAssets().open(EXTERNAL_MODULES_FILENAME)) { return parseStream(stream); } catch (FileNotFoundException e) { logger.log(SentryLevel.INFO, "%s file was not found.", EXTERNAL_MODULES_FILENAME); diff --git a/sentry-apache-http-client-5/src/main/java/io/sentry/transport/apache/ApacheHttpClientTransport.java b/sentry-apache-http-client-5/src/main/java/io/sentry/transport/apache/ApacheHttpClientTransport.java index 8ff2aa01bf..5e22089c9b 100644 --- a/sentry-apache-http-client-5/src/main/java/io/sentry/transport/apache/ApacheHttpClientTransport.java +++ b/sentry-apache-http-client-5/src/main/java/io/sentry/transport/apache/ApacheHttpClientTransport.java @@ -194,10 +194,11 @@ public void close() throws IOException { options.getLogger().log(DEBUG, "Shutting down"); try { httpclient.awaitShutdown(TimeValue.ofSeconds(1)); - httpclient.close(CloseMode.GRACEFUL); } catch (InterruptedException e) { options.getLogger().log(DEBUG, "Thread interrupted while closing the connection."); Thread.currentThread().interrupt(); + } finally { + httpclient.close(CloseMode.GRACEFUL); } } diff --git a/sentry/src/main/java/io/sentry/EnvelopeReader.java b/sentry/src/main/java/io/sentry/EnvelopeReader.java index 40c049a4df..0e7c95b1e4 100644 --- a/sentry/src/main/java/io/sentry/EnvelopeReader.java +++ b/sentry/src/main/java/io/sentry/EnvelopeReader.java @@ -133,14 +133,16 @@ public EnvelopeReader(@NotNull ISerializer serializer) { private @Nullable SentryEnvelopeHeader deserializeEnvelopeHeader( final @NotNull byte[] buffer, int offset, int length) { String json = new String(buffer, offset, length, UTF_8); - StringReader reader = new StringReader(json); - return serializer.deserialize(reader, SentryEnvelopeHeader.class); + try (StringReader reader = new StringReader(json)) { + return serializer.deserialize(reader, SentryEnvelopeHeader.class); + } } private @Nullable SentryEnvelopeItemHeader deserializeEnvelopeItemHeader( final @NotNull byte[] buffer, int offset, int length) { String json = new String(buffer, offset, length, UTF_8); - StringReader reader = new StringReader(json); - return serializer.deserialize(reader, SentryEnvelopeItemHeader.class); + try (StringReader reader = new StringReader(json)) { + return serializer.deserialize(reader, SentryEnvelopeItemHeader.class); + } } } diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index 0ce59cc05c..626ac588dd 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -13,6 +13,7 @@ import io.sentry.util.Pair; import io.sentry.util.TracingUtils; import java.io.Closeable; +import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.List; @@ -337,7 +338,13 @@ public void close() { try { for (Integration integration : options.getIntegrations()) { if (integration instanceof Closeable) { - ((Closeable) integration).close(); + try { + ((Closeable) integration).close(); + } catch (IOException e) { + options + .getLogger() + .log(SentryLevel.WARNING, "Failed to close the integration {}.", integration, e); + } } } diff --git a/sentry/src/main/java/io/sentry/JsonSerializer.java b/sentry/src/main/java/io/sentry/JsonSerializer.java index c00f2ad029..fbdc76d65e 100644 --- a/sentry/src/main/java/io/sentry/JsonSerializer.java +++ b/sentry/src/main/java/io/sentry/JsonSerializer.java @@ -126,8 +126,7 @@ public JsonSerializer(@NotNull SentryOptions options) { @NotNull Reader reader, @NotNull Class clazz, @Nullable JsonDeserializer elementDeserializer) { - try { - JsonObjectReader jsonObjectReader = new JsonObjectReader(reader); + try (JsonObjectReader jsonObjectReader = new JsonObjectReader(reader)) { if (Collection.class.isAssignableFrom(clazz)) { if (elementDeserializer == null) { // if the object has no known deserializer we do best effort and deserialize it as map @@ -147,8 +146,7 @@ public JsonSerializer(@NotNull SentryOptions options) { @SuppressWarnings("unchecked") @Override public @Nullable T deserialize(@NotNull Reader reader, @NotNull Class clazz) { - try { - JsonObjectReader jsonObjectReader = new JsonObjectReader(reader); + try (JsonObjectReader jsonObjectReader = new JsonObjectReader(reader)) { JsonDeserializer deserializer = deserializersByClass.get(clazz); if (deserializer != null) { Object object = deserializer.deserialize(jsonObjectReader, options.getLogger()); diff --git a/sentry/src/main/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoader.java b/sentry/src/main/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoader.java index b162ee020c..8c98edfefc 100644 --- a/sentry/src/main/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoader.java +++ b/sentry/src/main/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoader.java @@ -30,19 +30,23 @@ public ResourcesDebugMetaLoader(final @NotNull ILogger logger) { @Override public @Nullable Properties loadDebugMeta() { - InputStream debugMetaStream = classLoader.getResourceAsStream(DEBUG_META_PROPERTIES_FILENAME); - if (debugMetaStream == null) { - logger.log(SentryLevel.INFO, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME); - } else { - try (final InputStream is = new BufferedInputStream(debugMetaStream)) { - final Properties properties = new Properties(); - properties.load(is); - return properties; - } catch (IOException e) { - logger.log(SentryLevel.ERROR, e, "Failed to load %s", DEBUG_META_PROPERTIES_FILENAME); - } catch (RuntimeException e) { - logger.log(SentryLevel.ERROR, e, "%s file is malformed.", DEBUG_META_PROPERTIES_FILENAME); + try (final InputStream debugMetaStream = + classLoader.getResourceAsStream(DEBUG_META_PROPERTIES_FILENAME)) { + if (debugMetaStream == null) { + logger.log(SentryLevel.INFO, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME); + } else { + try (final InputStream is = new BufferedInputStream(debugMetaStream)) { + final Properties properties = new Properties(); + properties.load(is); + return properties; + } catch (IOException e) { + logger.log(SentryLevel.ERROR, e, "Failed to load %s", DEBUG_META_PROPERTIES_FILENAME); + } catch (RuntimeException e) { + logger.log(SentryLevel.ERROR, e, "%s file is malformed.", DEBUG_META_PROPERTIES_FILENAME); + } } + } catch (IOException e) { + logger.log(SentryLevel.ERROR, e, "Failed to load %s", DEBUG_META_PROPERTIES_FILENAME); } return null; diff --git a/sentry/src/main/java/io/sentry/internal/modules/ResourcesModulesLoader.java b/sentry/src/main/java/io/sentry/internal/modules/ResourcesModulesLoader.java index 11504cc0cc..8d583c8ab9 100644 --- a/sentry/src/main/java/io/sentry/internal/modules/ResourcesModulesLoader.java +++ b/sentry/src/main/java/io/sentry/internal/modules/ResourcesModulesLoader.java @@ -4,6 +4,7 @@ import io.sentry.ILogger; import io.sentry.SentryLevel; +import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.TreeMap; @@ -28,9 +29,8 @@ public ResourcesModulesLoader(final @NotNull ILogger logger) { @Override protected Map loadModules() { final Map modules = new TreeMap<>(); - try { - final InputStream resourcesStream = - classLoader.getResourceAsStream(EXTERNAL_MODULES_FILENAME); + try (final InputStream resourcesStream = + classLoader.getResourceAsStream(EXTERNAL_MODULES_FILENAME)) { if (resourcesStream == null) { logger.log(SentryLevel.INFO, "%s file was not found.", EXTERNAL_MODULES_FILENAME); @@ -40,6 +40,8 @@ protected Map loadModules() { return parseStream(resourcesStream); } catch (SecurityException e) { logger.log(SentryLevel.INFO, "Access to resources denied.", e); + } catch (IOException e) { + logger.log(SentryLevel.INFO, "Access to resources failed.", e); } return modules; }