Skip to content

Application crashes with java.util.concurrent.TimeoutException io.objectbox.BoxStore.close:707 #1201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
avarughese-tripactions opened this issue Jan 10, 2025 · 8 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists

Comments

@avarughese-tripactions
Copy link

avarughese-tripactions commented Jan 10, 2025

Is there an existing issue?

Build info

  • ObjectBox version: 4.0.3
  • OS: Android 13, 14 and 15
  • Device/ABI/architecture: happening across various OEM's and models. Some samples is Pixel 8 pro, Pixel8, Pixel 6a, Open CPH2551 etc

Steps to reproduce

We cannot reproduce the issue so far. It's happening at random in production with the new version upgrade from 3.7.1 to 4.0.3. The majority cases are happening right at the start/initialization of Object Box. But there are cases where we are seeing this crash quite randomly while the app is running

Expected behavior

The app should not crash

Actual behavior

The app is mostly crashing right at startup and sometimes randomly while in middle of execution.

Code

Code
This is how we do the initialization 

try {
   
    val builder = MyObjectBox.builder()
    boxStore = builder.androidContext(context)
        .name(custom_name)
        .build()
} catch (error: DbException) {

   boxStore?.removeAllObjects()
    if(!retry){
		// try it one more time
    }
}

Logs, stack traces

java.util.concurrent.TimeoutException: io.objectbox.BoxStore.finalize() timed out after 10 seconds
at io.objectbox.BoxStore.close(BoxStore:707)
at io.objectbox.BoxStore.finalize(BoxStore:525)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:370)
at java.lang.Daemons$FinalizerDaemon.processReference(Daemons.java:350)
at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:322)
at java.lang.Daemons$Daemon.run(Daemons.java:131)
at java.lang.Thread.run(Thread.java:1012)

Logs
[Paste your logs here]
@avarughese-tripactions avarughese-tripactions added the bug Something isn't working label Jan 10, 2025
@greenrobot-team
Copy link
Member

Thanks for reporting! See #1190 (comment).

Note: I labeled this issue with "more info required" so it will auto-close in a few days if there are no follow-up comments.

@greenrobot-team greenrobot-team added duplicate This issue or pull request already exists more info required Further information is requested labels Jan 13, 2025
@avarughese-tripactions
Copy link
Author

can you please provide some pointers on what kind of info you are looking for?

@github-actions github-actions bot removed the more info required Further information is requested label Jan 16, 2025
@RobbWatershed
Copy link

Interesting! I've been analyzing that very same issue on my app for weeks without any clear clue either.

I can't completely blame ObjectBox v4 as I've been migrating all my code to Kotlin at the same time, but I can't rule it out either.

@RobbWatershed
Copy link

RobbWatershed commented Jan 18, 2025

One more info : I've been extensively reviewing threaded Box operations and made sure to call BoxStore.closeThreadResources() on the same thread that did the operations, using a finally block. That didn't really help in my case.

@avarughese-tripactions
Copy link
Author

avarughese-tripactions commented Jan 18, 2025

We figured out the problem. So basically what we see is while creating the Boxstore object it checks if a file is already open. If it is open it creates a checker thread which calls the system.gc while acquiring lock to the openFiles object. It tries to run finalization by looping. Meanwhile if the gc gets invoked then close() function is called via finalize(). This GC thread tries to acquire the lock on openFiles object which is not available. They get in to a deadlock situation causing a timeout
This is the call stack scenario:
BoxStore constrauctor-> verifyNotAlreadyOpen-> isFileOpen -> checkerThread
checkerThread -> isFileOpenSync-> locks openFiles
GC thread -> Finalize -> Close -> waits to acquire lock on openFiles

we had a corner case in the code which might try to create a new instance while previous one is not closed hence triggering this. Although we think the architecture of ObjectBox creation might need a change to avoid this deadlock
Also, it doesn't look like lib version specific.
I will let the ObjectBox to comment

@RobbWatershed
Copy link

we had a corner case in the code which might try to create a new instance while previous one is not closed hence triggering this.

If you mean an instance of BoxStore, aren't we supposed to create it inside a Singleton?

@avarughese-tripactions
Copy link
Author

Yes, it should be singleton but we had a bug and that's triggering this issue for us. That's what we think

@greenrobot-team
Copy link
Member

greenrobot-team commented Jan 20, 2025

@avarughese-tripactions Thank you very much for the analysis and details! From what I remember it sounds plausible and we will have a look!

Edit: for our reference, the internal issue for this is objectbox-java#240

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants