sentry-java icon indicating copy to clipboard operation
sentry-java copied to clipboard

Initialize SentryOptions members lazily

Open romtsn opened this issue 2 years ago • 1 comments

Description

When SentryOptions.empty() is used (e.g. in a NoOpHub), we still eagerly initialize some of the class members, for example:

I think, those should be fine to initialize lazily, so in case of the empty options they do not cause potential issues. There was a recent customer report of an ANR caused by with Sentry frames in it (although the ANR is most likely not caused by Sentry, because there's nothing involved that should cause an ANR, but still we'd like to eliminate such issues):

main (runnable):tid=1 systid=27171 
       at io.sentry.JsonSerializer.<init>(JsonSerializer.java:84)
       at io.sentry.SentryOptions.<init>(SentryOptions.java:99)
       at io.sentry.SentryOptions.empty(SentryOptions.java:1899)
       at io.sentry.NoOpHub.<init>(NoOpHub.java:14)
       at io.sentry.NoOpHub.<clinit>(NoOpHub.java:12)
       at io.sentry.Sentry.<clinit>(Sentry.java:29)
       at io.sentry.HubAdapter.getSpan(HubAdapter.java:246)
       at io.sentry.instrumentation.file.FileIOSpanManager.startSpan(FileIOSpanManager.java:26)
       at io.sentry.instrumentation.file.SentryFileInputStream.init(SentryFileInputStream.java:65)
       at io.sentry.instrumentation.file.SentryFileInputStream.access$000(SentryFileInputStream.java:22)
       at io.sentry.instrumentation.file.SentryFileInputStream$Factory.create(SentryFileInputStream.java:137)
       at com.google.firebase.crashlytics.internal.settings.CachedSettingsIo.readCachedSettings(CachedSettingsIo.java:56)
       at com.google.firebase.crashlytics.internal.settings.SettingsController.getCachedSettingsData(SettingsController.java:235)
       at com.google.firebase.crashlytics.internal.settings.SettingsController.loadSettingsData(SettingsController.java:169)
       at com.google.firebase.crashlytics.internal.settings.SettingsController.loadSettingsData(SettingsController.java:154)
       at com.google.firebase.crashlytics.FirebaseCrashlytics.init(FirebaseCrashlytics.java:136)
       at com.google.firebase.crashlytics.CrashlyticsRegistrar.buildCrashlytics(CrashlyticsRegistrar.java:57)
       at com.google.firebase.crashlytics.CrashlyticsRegistrar.$r8$lambda$Pfd5XmDCFzNyAT9o9H6rDnTBQE4(CrashlyticsRegistrar.java)
       at com.google.firebase.crashlytics.CrashlyticsRegistrar$$InternalSyntheticLambda$1$ab347a8933944304e42539e3f0bc7a2eb5ded1d56c7a52feedae47ac52780cf7$0.create(CrashlyticsRegistrar.java:2)
       at com.google.firebase.components.ComponentRuntime.lambda$discoverComponents$0(ComponentRuntime.java:132)
       at com.google.firebase.components.ComponentRuntime.$r8$lambda$4FqOW9eOQsvFYo-HpMfxCOnPQr0(ComponentRuntime.java)
       at com.google.firebase.components.ComponentRuntime$$InternalSyntheticLambda$0$784536aca87f12f75d3504e86fd606a2ca102f8312a2daf2c8c51b9b25617f63$0.get(ComponentRuntime.java:4)
       at com.google.firebase.components.Lazy.get(Lazy.java:53)
       at com.google.firebase.components.ComponentRuntime.doInitializeEagerComponents(ComponentRuntime.java:291)
       at com.google.firebase.components.ComponentRuntime.initializeEagerComponents(ComponentRuntime.java:281)
       at com.google.firebase.FirebaseApp.initializeAllApis(FirebaseApp.java:584)
       at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:303)
       at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:267)
       at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:252)
       at com.google.firebase.provider.FirebaseInitProvider.onCreate(FirebaseInitProvider.java:51)
       at android.content.ContentProvider.attachInfo(ContentProvider.java:2404)
       at android.content.ContentProvider.attachInfo(ContentProvider.java:2374)
       at com.google.firebase.provider.FirebaseInitProvider.attachInfo(FirebaseInitProvider.java:45)
       at android.app.ActivityThread.installProvider(ActivityThread.java:7524)
       at android.app.ActivityThread.installContentProviders(ActivityThread.java:7041)
       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6790)
       at android.app.ActivityThread.access$1600(ActivityThread.java:255)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2100)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7941)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009)

romtsn avatar Feb 14 '23 20:02 romtsn

We could even lazily initialize elements of SentryOptions on options.getXYZ() to defer object init.

markushi avatar Feb 15 '23 15:02 markushi