Thanks for sharing this. I hadn't previously stumbled across JNA, but it seems to support Android, so maybe it would be a good way to use general-purpose Rust libraries within Android apps without writing a lot of new JNI shim code.
I'm sorta blown away at the complexity and overhead of making a native call in Java. Looks like this was one if the areas Microsoft was improving in Java, with J/Direct? In comparison, calling native code from the CLR is a one-line affair. Even two-way; you just pass a delegate and the runtime creates a thunk on the fly.
Yes, and this was not something that demanded attention because Java originally wanted to discourage the use of native -- and platform specific -- code. So JNI was originally thought of as a bridge you build once to your legacy C code, and then move on. Recently, people have been wanting a more liberal use of native 3rd party libraries, so this issue is getting fixed with JNR[1], which will serve as the basis of Java's new FFI being developed under Project Panama[2].
JNA bridging is not that useful in Android's context though :( .
Sure, you can write some parts of your code in Rust, but anything that uses a platform API will still have to be written in Java.
I would not mind to see Google replace Java by Rust coming next IO.
I was thinking more along the lines of libraries supporting protocols, formats, cryptosystems, and the like -- stuff that doesn't require interacting with the Android API.
Being able to use the Android API from Rust (or any other non-Java language) is an interesting problem, though. Unfortunately, as you mention, the API is strongly tied to specific Java/Dalvik classes and methods (the stuff in framework.jar). Many of these merely proxy to backend services over Binder/AIDL, but the Binder/AIDL calls and associated data structures are subject to change. Sometimes I wish there was a standardized interface for native code to communicate directly with backend services over Binder, but that would likely create more headaches than it would fix.
I am not sure their are a lot of use-cases for this where there is not already a great java or c++ library. So I fear that it might not make a lot of sense to use Rust for most apps.
Regarding the API, IMO a solution can only come from Google.
There are good arguments in favor of replacing Java by Rust (or a Rust inspired language managed by Google) and even to rewrite the app framework foundations in order to improve the current offering. Officially, Java is the language of the platform, but that does not necessarily mean that they won't replace it in time.
It's probably possible to create a situation where a JVM process calls Rust code which then calls back to some Java function, if you're inclined to spend enough time hacking with JNI (is it possible to pass a function pointer out of JVM land?). But if you started as a native Rust process, there's no JVM runtime to call into, you'd need start that up first.
It's definitely possible to bootstrap the JVM in-process but there are quite some steps to it and it requires a bunch of platform dependent code to locate and load the library via LoadLibrary(jvm.dll) / dlopen(libjvm.so). IIRC the JNI functions all have C linkage so it should be easy to do from Rust.
I think the continuation of this would be a neat project. The lib starts up a JVM, it would be interesting to see a macro [1] (or will probably have to be a compiler plugin [2]) to model Java objects and make it clear the ownership of memory.
17 comments
[ 4.8 ms ] story [ 40.2 ms ] thread[1]: https://github.com/jnr/jnr-ffi
[2]: http://openjdk.java.net/projects/panama/
Being able to use the Android API from Rust (or any other non-Java language) is an interesting problem, though. Unfortunately, as you mention, the API is strongly tied to specific Java/Dalvik classes and methods (the stuff in framework.jar). Many of these merely proxy to backend services over Binder/AIDL, but the Binder/AIDL calls and associated data structures are subject to change. Sometimes I wish there was a standardized interface for native code to communicate directly with backend services over Binder, but that would likely create more headaches than it would fix.
Regarding the API, IMO a solution can only come from Google. There are good arguments in favor of replacing Java by Rust (or a Rust inspired language managed by Google) and even to rewrite the app framework foundations in order to improve the current offering. Officially, Java is the language of the platform, but that does not necessarily mean that they won't replace it in time.
I haven't tried it, but it looks featureful enough to be useful.
[1] https://github.com/Monnoroch/RustJni
1 - http://doc.rust-lang.org/0.12.0/guide.html#macros 2 - http://doc.rust-lang.org/0.12.0/guide-plugin.html