Java is not something I am very happy about working with, personal dislike aside, I have had a lot of peers discourage me from working with it. But when it comes to interesting technical challenges, it is always a good idea to atleast give it a try. Now that I am at a point where I have spent close to a month on the task, I feel I am more than enough experienced to give my first impressions and more importantly a note of caution to folks who might be considering jumping into the depths, in search of an adventure.
JNI is complex, but it isn't like you have to deal with a lot of the complexity yourself. If you have the advantage of being able to use a simple, yet awesome developer tool called flapigen
, you are already off to the races! Yes, I had tried writing the bindings myself, but it wasn't a very good idea, the ability to write code with a DSL and have it generate the bindings is as miracle cure to some of the worst problems a maintainer can face. Flapigen gives you a simple rust-macro styled programming language that you can use to define JNI bindings for your library. It is as simple as:
// rust code
pub struct Foo();
impl Foo {
pub fn new() -> Foo {
Foo()
}
}
pub fn hello() -> String {
"Hello, World".to_owned()
}
// flapigen code
foreign_class!(class Foo {
self_type Foo;
constructor Foo::new() -> Foo;
fn hello() -> String;
});
The above code describes a struct that serves no other purpose than to be a placeholder object that is used to call hello()
from Java. Once the equivalent Java code is generated, you'll be able to use the bindings as follows:
import rust.package.Foo;
class Bar {
public void hello() {
Foo foo = new Foo();
System.out.println(foo.hello());
}
}
NOTE: Given that you have loaded the proper .so
that was also generated when building the rust library.