react-native-vision-camera: šŸ› JNI Crash when trying to use multiple Frame Processor Plugins in a single Frame Processor

Question

Hi,

Hi created two test plugins, (Plugin1, Plugin2) based on the ExamplePlugin.

They have been added a to Package and added to the MainApplication as per the examples provided.

In my App I call both of them here, which causes the app to consistently crash with the following error:

2021-09-14 21:17:03.138 12726-12883/com.meshcameratest A/.meshcamerates: java_vm_ext.cc:577] JNI DETECTED ERROR IN APPLICATION: can't call java.lang.Object com.meshcameratest.frameprocessors.ExamplePlugin1.callback(androidx.camera.core.ImageProxy, java.lang.Object[]) on instance of com.meshcameratest.frameprocessors.ExamplePlugin2
    java_vm_ext.cc:577]     in call to CallObjectMethodV
    java_vm_ext.cc:577]     from void com.mrousavy.camera.CameraView.frameProcessorCallback(androidx.camera.core.ImageProxy)

The crash will always occur on the second call regardless of order. No crash occurs if I run call just a single plugin.

It’s very possible I’m missing some fundamental understanding of what you can and cannot do within a worklet, hence this is phrased as a question rather than a bug.

Any guidance appreciated.

Example repo available at https://github.com/ldstein/MeshCameraTest

What I tried

  • Register plugins directly in onCreate
  • Moved packages around
  • Clear cache in metro, gradle
  • Ensure react-reanimated plugin + setup is complete

VisionCamera Version

2.7.0

Additional information

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 40 (30 by maintainers)

Most upvoted comments

lol, fresh

will clean up the PR and merge when I get home

You can’t usefully register the Hades GC thread, because there’s no way to safely unregister it.

I mean you would have some queue which you could add to in native from any thread, and read from on a java thread, which would destroy the references added to the queue. This is mostly independent from JNI.

Maybe the Hermes garbage collector (Hades) does not run on the same Thread?

That’s correct. From jsi.h: ā€œThe [HostObject] C++ object’s dtor will be called when the GC finalizes this object. (This may be as late as when the Runtime is shut down.) You have no control over which thread it is called on.ā€ Before Hades, this would always happen synchronously, but one of the ways Hades reduces JS stalls is by sometimes calling dtors on a separate thread. If you need to delete an fbjni global_ref, then you need to arrange to queue that work on a Java-registered thread (preferred), or use ThreadScope::WithClassLoader to temporarily register the current thread.

@mrousavy: I can confirm that is also works for me. I mentioned a few hours ago that was not working, but was clearly my fault: C++ libraries were not properly cleaned up. After deleting cached ones it worked as expected. Thanks!

gonna report abuse on that gist because that’s the weirdest thing I’ve ever seen Screenshot 2021-09-23 at 15 06 41

what the f

Running two frame processors appears to work fine on iOS, tested on an iPhone 7 device running iOS 13.6.1. I had to downgrade the reanimated version to 2.2.2 (from the alpha used in the examples) as it seems the reanimated pods reference react-native-screens for some reason which gave a build error.

So it looks like this is purely an Android issue. I tried separating the two test plugins into their own Android packages to see if that made a difference but it didn’t.

Why the callback from one plugin is been called from the other one?

Yeah I also don’t get that. The past few days have been really busy for me so I couldn’t investigate this further, I hope I can find some free time to do that soon.

ohh no, this is crucial for a project that i’m involved šŸ˜•