-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I really like this library! The idea of using the Capability to enforce handling of JNI errors at compile time (rather than having to remember to check for them each time) is great! Also the nice Rust wrappers around a lot of the JNIEnv functions are super useful.
I've been trying to get this to work on Android in what seems to be somewhat the opposite direction the library was originally intended for. Rather than starting up the JVM from Rust, I'm calling into Rust functions from an existing JVM. This poses a number of problems. I had a few I ideas on how to solve them, but I was curious if you have thoughts on potential solutions. The main issues so far are:
- When Java calls into Rust, you only get a pointer to the JNIEnv, not the full JavaVm. I think it could be useful to have a constructor that consumes this pointer and returns the wrapper object, maybe with a dummy JVM. It is possible to store off the JVM in a static variable in JNIOnLoad, so another alternative is to pass in a reference to that when creating the
JNIEnvRust object. - You need an initial
Capabilityobject. I think it would be reasonable to have the constructor for theJNIEnvwrapper return the result of theexception_checkmethod. - When returning a value, if one of the Rust wrappers is used, like
JavaString, thedropimplementation deletes the local reference before the function returns, causing a local reference table overflow exception. One possibility here is to have the as_ptr method consume the object and prevent deleting the ref. You'd probably want to make it unsafe at that since it allows you to leak memory, especially if it's a global reference (or even disable this for global references). - Similarly, it doesn't seem possible to have long-lived objects, particularly global references. Since the Rust wrapper objects have a
JNIEnvreference, they can't outlive the function in which that env is created. Normally that's exactly what you want, but I need the ability to store off global references in long-lived data structures. Similar to returning a local ref, one approach could be to have a function that converts the object to a long-living one by somehow losing the reference to the env. Unlike the local ref case, you could still have the object delete its global ref in itsdropimplementation. - I didn't see any way to invoke Java methods or instantiate new Java objects. Is there something I'm missing there, or is that functionality not implemented yet?
I'm happy to work on these and submit pull requests for them, but I wanted to see if you had thoughts on these issues before jumping into it. Thanks!