Skip to content

Sentry Android NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference #2196

Description

@Leeonardoo

Integration

sentry-android

Build System

Gradle

AGP Version

7.2.1

Proguard

Enabled

Version

6.3.0

Steps to Reproduce

Unknown

Expected Result

The app shouln't crash because of tracing

Actual Result

I'm randomly getting a bunch of crashes caused by the call to timer.cancel() on SentryTracer (both using navigation-compose integration and also without it). Actually taking a look into it seems like it's failing because of this block of code.

You can see it's checking if the timer != null outside of the syncronized block, so presumably another thread could change it to null but the check has already passed on another thread. So I think the fix would be to just change it like it's been done on the cancelTimer method.

Also, i'm using the gradle plugin on my build.gradle file, like so:

plugins {
    id("com.android.application")
    //other plugins ...
    id("io.sentry.android.gradle") version "3.1.3"
}

Here are the crash logs (you can see one of them are even unrelated to navigation or compose):

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference
       at io.sentry.SentryTracer.finish(SentryTracer.java:347)
       at io.sentry.SentryTracer$1.run(SentryTracer.java:130)
       at java.util.TimerThread.mainLoop(TimerThread.java:562)
       at java.util.TimerThread.run(TimerThread.java:512)
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference
       at io.sentry.SentryTracer.finish(SentryTracer.java:347)
       at io.sentry.android.navigation.SentryNavigationListener.stopTracing(SentryNavigationListener.kt:137)
       at io.sentry.android.navigation.SentryNavigationListener.startTracing(SentryNavigationListener.kt:93)
       at io.sentry.android.navigation.SentryNavigationListener.onDestinationChanged(SentryNavigationListener.kt:49)
       at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.kt:902)
       at androidx.navigation.NavController.navigate(NavController.kt:1730)
       at androidx.navigation.NavController.navigate(NavController.kt:1662)
       at androidx.navigation.NavController.navigate(NavController.kt:1984)
       at androidx.navigation.NavController.navigate$default(NavController.kt:1979)
       at androidx.navigation.NavController.navigate(NavController.kt:1965)
       at com.ramcosta.composedestinations.navigation.DestinationsNavController.navigate(DestinationsNavController.kt:27)
       at com.ramcosta.composedestinations.navigation.DestinationsNavigator$DefaultImpls.navigate(DestinationsNavigator.java:40)
       at com.ramcosta.composedestinations.navigation.DestinationsNavController.navigate(DestinationsNavController.kt:13)
       at com.ramcosta.composedestinations.navigation.DestinationsNavigator$DefaultImpls.navigate$default(DestinationsNavigator.kt:35)
       at com.myapp.ui.MyScreenKt$MyScreenContent$1$3.invoke(MyScreen.kt:120)
       at com.myapp.ui.MyScreenKt$MyScreenContent$1$3.invoke(MyScreen.kt:115)
       at com.myapp.ui.MyScreenItemKt$MyScreenItem$1$1.invoke(MyScreenItem.kt:33)
       at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke-k-4lQ0M(Clickable.kt:153)
       at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke(Clickable.kt:142)
       at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1$1.invokeSuspend(TapGestureDetector.kt:222)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
       at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTaskKt.java:166)
       at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
       at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.java:566)
       at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:456)
       at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:469)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:310)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
       at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(NodeParent.java:179)
       at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:98)
       at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:97)
       at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1321)
       at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1267)
       at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1206)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
       at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:1015)
       at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1962)
       at android.app.Activity.dispatchTouchEvent(Activity.java:4265)
       at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:70)
       at io.sentry.android.core.internal.gestures.WindowCallbackAdapter.dispatchTouchEvent(WindowCallbackAdapter.java:39)
       at io.sentry.android.core.internal.gestures.SentryWindowCallback.dispatchTouchEvent(SentryWindowCallback.java:64)
       at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:973)
       at android.view.View.dispatchPointerEvent(View.java:15335)
       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:7807)
       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:7580)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6914)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6971)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6937)
       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:7135)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6945)
       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:7192)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6918)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6971)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6937)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6945)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6918)
       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:10367)
       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:10215)
       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:10171)
       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:10499)
       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:259)
       at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
       at android.os.MessageQueue.next(MessageQueue.java:335)
       at android.os.Looper.loopOnce(Looper.java:186)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8680)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Metadata

Metadata

Assignees

Labels

BugIssue type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions