Skip to content

Commit f17b109

Browse files
authored
Merge e39c7c2 into fc52bb8
2 parents fc52bb8 + e39c7c2 commit f17b109

File tree

11 files changed

+57
-41
lines changed

11 files changed

+57
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
### Fixes
3232

3333
- Fix crash when unregistering `SystemEventsBroadcastReceiver` with try-catch block. ([#5106](https://github.com/getsentry/sentry-java/pull/5106))
34+
- Reduce allocations and bytecode instructions during `Sentry.init` ([#5135](https://github.com/getsentry/sentry-java/pull/5135))
3435

3536
### Dependencies
3637

sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static void loadDefaultAndMetadataOptions(
142142

143143
readDefaultOptionValues(options, finalContext, buildInfoProvider);
144144
AppState.getInstance().registerLifecycleObserver(options);
145+
options.activate();
145146
}
146147

147148
@TestOnly
@@ -200,7 +201,7 @@ static void initializeIntegrationsAndProcessors(
200201
final @NotNull AppStartMetrics appStartMetrics = AppStartMetrics.getInstance();
201202

202203
if (options.getModulesLoader() instanceof NoOpModulesLoader) {
203-
options.setModulesLoader(new AssetsModulesLoader(context, options.getLogger()));
204+
options.setModulesLoader(new AssetsModulesLoader(context, options));
204205
}
205206
if (options.getDebugMetaLoader() instanceof NoOpDebugMetaLoader) {
206207
options.setDebugMetaLoader(new AssetsDebugMetaLoader(context, options.getLogger()));

sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package io.sentry.android.core.internal.modules;
22

33
import android.content.Context;
4-
import io.sentry.ILogger;
54
import io.sentry.SentryLevel;
5+
import io.sentry.SentryOptions;
66
import io.sentry.android.core.ContextUtils;
77
import io.sentry.internal.modules.ModulesLoader;
88
import java.io.FileNotFoundException;
@@ -18,13 +18,21 @@ public final class AssetsModulesLoader extends ModulesLoader {
1818

1919
private final @NotNull Context context;
2020

21-
public AssetsModulesLoader(final @NotNull Context context, final @NotNull ILogger logger) {
22-
super(logger);
21+
public AssetsModulesLoader(final @NotNull Context context, final @NotNull SentryOptions options) {
22+
super(options.getLogger());
2323
this.context = ContextUtils.getApplicationContext(context);
2424

2525
// pre-load modules on a bg thread to avoid doing so on the main thread in case of a crash/error
26-
//noinspection Convert2MethodRef
27-
new Thread(() -> getOrLoadModules()).start();
26+
try {
27+
options
28+
.getExecutorService()
29+
.submit(
30+
() -> {
31+
getOrLoadModules();
32+
});
33+
} catch (Throwable e) {
34+
options.getLogger().log(SentryLevel.ERROR, "AssetsModulesLoader submit failed", e);
35+
}
2836
}
2937

3038
@Override

sentry-android-core/src/test/java/io/sentry/android/core/SentryAndroidTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.sentry.DateUtils
1616
import io.sentry.Hint
1717
import io.sentry.ILogger
1818
import io.sentry.ISentryClient
19+
import io.sentry.NoOpSentryExecutorService
1920
import io.sentry.Sentry
2021
import io.sentry.Sentry.OptionsConfiguration
2122
import io.sentry.SentryEnvelope
@@ -528,6 +529,19 @@ class SentryAndroidTest {
528529
assertEquals(99, AppStartMetrics.getInstance().appStartTimeSpan.startUptimeMs)
529530
}
530531

532+
@Test
533+
fun `executor service is not NoOp when AndroidConnectionStatusProvider is initialized`() {
534+
var executorServiceIsNoOp = true
535+
fixture.initSut(context = context) { options ->
536+
options.dsn = "https://key@sentry.io/123"
537+
// the config callback runs before initializeIntegrationsAndProcessors, which creates
538+
// AndroidConnectionStatusProvider - so if the executor is already real here,
539+
// it's guaranteed to be real when the provider calls submitSafe()
540+
executorServiceIsNoOp = options.executorService is NoOpSentryExecutorService
541+
}
542+
assertFalse(executorServiceIsNoOp)
543+
}
544+
531545
@Test
532546
fun `if the config options block throws still intializes android event processors`() {
533547
lateinit var optionsRef: SentryOptions

sentry-android-core/src/test/java/io/sentry/android/core/internal/modules/AssetsModulesLoaderTest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package io.sentry.android.core.internal.modules
22

33
import android.content.Context
44
import android.content.res.AssetManager
5-
import io.sentry.ILogger
5+
import io.sentry.SentryOptions
6+
import io.sentry.test.ImmediateExecutorService
67
import java.io.FileNotFoundException
78
import java.nio.charset.Charset
89
import kotlin.test.Test
@@ -16,7 +17,7 @@ class AssetsModulesLoaderTest {
1617
class Fixture {
1718
val context = mock<Context>()
1819
val assets = mock<AssetManager>()
19-
val logger = mock<ILogger>()
20+
val options = SentryOptions().apply { executorService = ImmediateExecutorService() }
2021

2122
fun getSut(
2223
fileName: String = "sentry-external-modules.txt",
@@ -31,7 +32,7 @@ class AssetsModulesLoaderTest {
3132
whenever(assets.open(fileName)).thenThrow(FileNotFoundException())
3233
}
3334
whenever(context.assets).thenReturn(assets)
34-
return AssetsModulesLoader(context, logger)
35+
return AssetsModulesLoader(context, options)
3536
}
3637
}
3738

sentry/src/main/java/io/sentry/DuplicateEventDetectionEventProcessor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.sentry;
22

3-
import io.sentry.util.Objects;
43
import java.util.ArrayList;
54
import java.util.Collections;
65
import java.util.List;
@@ -16,7 +15,7 @@ public final class DuplicateEventDetectionEventProcessor implements EventProcess
1615
private final @NotNull SentryOptions options;
1716

1817
public DuplicateEventDetectionEventProcessor(final @NotNull SentryOptions options) {
19-
this.options = Objects.requireNonNull(options, "options are required");
18+
this.options = options;
2019
}
2120

2221
@Override

sentry/src/main/java/io/sentry/MainEventProcessor.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import io.sentry.protocol.SentryTransaction;
99
import io.sentry.protocol.User;
1010
import io.sentry.util.HintUtils;
11-
import io.sentry.util.Objects;
1211
import java.io.Closeable;
1312
import java.io.IOException;
1413
import java.util.ArrayList;
@@ -29,7 +28,7 @@ public final class MainEventProcessor implements EventProcessor, Closeable {
2928
private volatile @Nullable HostnameCache hostnameCache = null;
3029

3130
public MainEventProcessor(final @NotNull SentryOptions options) {
32-
this.options = Objects.requireNonNull(options, "The SentryOptions is required.");
31+
this.options = options;
3332

3433
final SentryStackTraceFactory sentryStackTraceFactory =
3534
new SentryStackTraceFactory(this.options);
@@ -38,17 +37,6 @@ public MainEventProcessor(final @NotNull SentryOptions options) {
3837
sentryThreadFactory = new SentryThreadFactory(sentryStackTraceFactory);
3938
}
4039

41-
MainEventProcessor(
42-
final @NotNull SentryOptions options,
43-
final @NotNull SentryThreadFactory sentryThreadFactory,
44-
final @NotNull SentryExceptionFactory sentryExceptionFactory) {
45-
this.options = Objects.requireNonNull(options, "The SentryOptions is required.");
46-
this.sentryThreadFactory =
47-
Objects.requireNonNull(sentryThreadFactory, "The SentryThreadFactory is required.");
48-
this.sentryExceptionFactory =
49-
Objects.requireNonNull(sentryExceptionFactory, "The SentryExceptionFactory is required.");
50-
}
51-
5240
@Override
5341
public @NotNull SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) {
5442
setCommons(event);

sentry/src/main/java/io/sentry/SentryExceptionFactory.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import io.sentry.protocol.SentryStackFrame;
77
import io.sentry.protocol.SentryStackTrace;
88
import io.sentry.protocol.SentryThread;
9-
import io.sentry.util.Objects;
109
import java.util.ArrayDeque;
1110
import java.util.ArrayList;
1211
import java.util.Deque;
@@ -31,8 +30,7 @@ public final class SentryExceptionFactory {
3130
* @param sentryStackTraceFactory the sentryStackTraceFactory
3231
*/
3332
public SentryExceptionFactory(final @NotNull SentryStackTraceFactory sentryStackTraceFactory) {
34-
this.sentryStackTraceFactory =
35-
Objects.requireNonNull(sentryStackTraceFactory, "The SentryStackTraceFactory is required.");
33+
this.sentryStackTraceFactory = sentryStackTraceFactory;
3634
}
3735

3836
@NotNull

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,24 @@ public void activate() {
655655
executorService = new SentryExecutorService(this);
656656
executorService.prewarm();
657657
}
658+
659+
// SpotlightIntegration is loaded via reflection to allow the sentry-spotlight module
660+
// to be excluded from release builds, preventing insecure HTTP URLs from appearing in APKs
661+
try {
662+
final Class<?> clazz = Class.forName("io.sentry.spotlight.SpotlightIntegration");
663+
boolean alreadyRegistered = false;
664+
for (final Integration integration : integrations) {
665+
if (clazz.isInstance(integration)) {
666+
alreadyRegistered = true;
667+
break;
668+
}
669+
}
670+
if (!alreadyRegistered) {
671+
integrations.add((Integration) clazz.getConstructor().newInstance());
672+
}
673+
} catch (Throwable ignored) {
674+
// SpotlightIntegration not available
675+
}
658676
}
659677

660678
/**
@@ -3340,16 +3358,6 @@ private SentryOptions(final boolean empty) {
33403358

33413359
integrations.add(new ShutdownHookIntegration());
33423360

3343-
// SpotlightIntegration is loaded via reflection to allow the sentry-spotlight module
3344-
// to be excluded from release builds, preventing insecure HTTP URLs from appearing in APKs
3345-
try {
3346-
final Class<?> clazz = Class.forName("io.sentry.spotlight.SpotlightIntegration");
3347-
final Integration spotlight = (Integration) clazz.getConstructor().newInstance();
3348-
integrations.add(spotlight);
3349-
} catch (Throwable ignored) {
3350-
// SpotlightIntegration not available
3351-
}
3352-
33533361
eventProcessors.add(new MainEventProcessor(this));
33543362
eventProcessors.add(new DuplicateEventDetectionEventProcessor(this));
33553363

sentry/src/main/java/io/sentry/SentryThreadFactory.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import io.sentry.protocol.SentryStackFrame;
44
import io.sentry.protocol.SentryStackTrace;
55
import io.sentry.protocol.SentryThread;
6-
import io.sentry.util.Objects;
76
import java.util.ArrayList;
87
import java.util.HashMap;
98
import java.util.List;
@@ -26,8 +25,7 @@ public final class SentryThreadFactory {
2625
* @param sentryStackTraceFactory the SentryStackTraceFactory
2726
*/
2827
public SentryThreadFactory(final @NotNull SentryStackTraceFactory sentryStackTraceFactory) {
29-
this.sentryStackTraceFactory =
30-
Objects.requireNonNull(sentryStackTraceFactory, "The SentryStackTraceFactory is required.");
28+
this.sentryStackTraceFactory = sentryStackTraceFactory;
3129
}
3230

3331
/**

0 commit comments

Comments
 (0)