Initializing the SDK more than once could causes an ANR
Integration
sentry-android
Build System
Gradle
AGP Version
7.2.1
Proguard
Enabled
Version
6.7.1
Steps to Reproduce
We are getting this issue on different devices in Firebase:
main (timed waiting):tid=1 systid=11706
at jdk.internal.misc.Unsafe.park(Unsafe.java)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1461)
at io.sentry.transport.AsyncHttpTransport.close(AsyncHttpTransport.java:139)
at io.sentry.SentryClient.close(SentryClient.java:740)
at io.sentry.Hub.close(Hub.java:346)
at io.sentry.Sentry.init(Sentry.java:200)
at io.sentry.Sentry.init(Sentry.java:125)
at io.sentry.android.core.SentryAndroid.init(SentryAndroid.java:89)
at io.sentry.android.core.SentryAndroid.init(SentryAndroid.java:70)
at com.package.SdkApplication.setmContext(SdkApplication.java:53)
at android.app.Activity.performCreate(Activity.java:8130)
at android.app.Activity.performCreate(Activity.java:8110)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1343)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3781)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3977)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:109)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2374)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8248)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)
```
Note that auto init is disabled, `<meta-data android:name="io.sentry.auto-init" android:value="false" />`
### Expected Result
App shouldn't crash.
### Actual Result
App is crashing on few phones on Android 11,12 and 13
I assume this is not a crash, but an ANR, looking at the stacktrace?
Also, it looks like you're initializing Sentry inside Activity.onCreate and not Application.onCreate as recommended in our docs - is there a specific reason for that?
Hi @romtsn , yes it is an ANR(Updated the title).
Our app is in react-native and one sdk is in Java(Android). We are using sentry in both and both are pointing to different sentry projects. The ANR is in the sdk. We can't use Application.onCreate in the sdk. Maybe this is the reason of this ANR?
Have you followed the manual setup steps for RN when setting up both SDKs?
Yes, for RN, we are using Autolinking as mentioned in the doc
@nandanxyz By default, the Android SDK is initialized automatically by the RN SDK. You can disable that and initialize the Android SDK manually.
Are you using the autoInitializeNativeSdk: false in RN?
Hi @krystofwoldrich , no we are not using autoInitializeNativeSdk: false in RN. But can we use sentry in both RN and Android sdk in the same project?
@krystofwoldrich could you please take a look at this again?
Just to recap,
you have a React Native app and you would like to use RN SDK with DSN1 and independent Android SDK with DSN2.
This should be possible, but we have not tested this scenario.
You would need to disable the native layer in the RN SDK (note that you might lose a lot of the SDK features depending on the Android SDK) and then initialize the Android SDK separately.
As you mentioned that you don't use autoInitializeNativeSdk: false I suspect the issue could be in initializing the Android SDK twice, once automatically by the RN SDK and once manually by you.
Could running init twice for the Android SDK be a problem @romtsn?
If you want to use all the features of the RN SDK the Android SDK needs to point to the same DSN.
Could you share code snippets of how you initialize both SDKs?
Thank you @krystofwoldrich
On React-Native:
const routingInstrumentation = new Sentry.ReactNavigationInstrumentation();
Sentry.init({
dsn: <DSN-1>,
tracesSampleRate: 0.3,
integrations: [
new Sentry.ReactNativeTracing({
idleTimeout: 5000,
routingInstrumentation,
tracingOrigins: ["localhost", /^\//, /^https:\/\//]
})
],
release: `${APPLICATIONID}@${DeviceInfo?.getVersion()}+${DeviceInfo?.getBuildNumber()}`,
dist: DeviceInfo?.getBuildNumber()
});
On Android:
<meta-data android:name="io.sentry.auto-init" android:value="false" />
<provider
android:name="io.sentry.android.core.SentryInitProvider"
android:authorities="${applicationId}.SentryInitProvider"
tools:node="remove" />
<provider
android:name="io.sentry.android.core.SentryPerformanceProvider"
android:authorities="${applicationId}.SentryPerformanceProvider"
tools:node="remove" />
and,
SentryAndroid.init(mContext, options -> {
options.setDsn(<DSN-2>);
options.setTracesSampleRate(1.0);
options.setEnableUserInteractionTracing(true);
options.setAnrEnabled(true);
options.setEnvironment(<ENV-name>);
options.setBeforeSend((event, hint) -> {
String environment = event.getEnvironment();
if (environment == null || environment.equals("TEST")) {
return null;
} else if(environment.equals(<ENV-name>)){
return event;
}else{
return null;
}
});
});
Could running init twice for the Android SDK be a problem @romtsn?
Yes, we do not recommend doing that, as there might be unpredictable consequences (like this issue). For the same reason we require to disable auto-init in the manifest when doing manual init.
However, I'm thinking we should still avoid this blocking transport termination on Android, or at least offload this to another thread when Hub.close is called, if possible. @markushi @stefanosiano what do you think about that?
We are getting this error. We have a multi-module application. Every module is using :base module and we have :app module. We described plugin like this:
plugins {
id 'com.android.application'
...
id 'io.sentry.android.gradle' version '3.12.0'
}
We used this plugin in both of base and app module. Maybe we can only describe in :app module. If I remove usage of plugin in base module. Can I solve this problem?
For the upcoming 7.0 release we reduced the flush timeouts (see https://github.com/getsentry/sentry-java/pull/2858)
On top of that we could even perform closing in a non-blocking way by simply creating a new thread pool whenever Sentry.init is called. This way the old instance can gracefully shutdown in the background.
I believe this was resolved by https://github.com/getsentry/sentry-java/pull/3200