Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create iOS static library from robovm project (BAD_ACCESS in JNI)

I have a large amount of Java code (only calculation functions, no UI) that I want to reuse as a static library in iOS. My approach was to use robovm and follow the unofficial way to create a static library described in the two articles in the robovm forum: 1 Basic way and 2 Refined version

Trying to follow the steps exactly as described I got stuck unfortunately after creating the shared library with the script, linking the library (.a) in Xcode and building the project successfully.

During runtime I see that my C++ bridge code is called but the JNI calls back to the library fail with a BAD_ACCESS. For example the following line crashes:

jclass myJavaClass = jniEnv->FindClass("com/test/robovm/bridge/MyJavaRoboCode");

in this method:

void callSomethingInJava(const char* arg) {
    // To call into java from your native app, use JNI
    Env* rvmEnv = rvmGetEnv();
    JNIEnv* jniEnv = &(rvmEnv->jni);
    jclass myJavaClass = jniEnv->FindClass("com/test/robovm/bridge/MyJavaRoboCode");
    jmethodID myJavaMethod = jniEnv->GetStaticMethodID(myJavaClass, "callJava", "(Ljava/lang/String;)V");
    jstring argAsJavaString = jniEnv->NewStringUTF(arg);
    jniEnv->CallStaticVoidMethod(myJavaClass, myJavaMethod, argAsJavaString);

}

The same is true if I try to use the rvmXX methods directly instead of JNI and try to access something in my "Java" classes. It looks like the rvmEnv is not fully initialized. (I double checked for package name errors or typos).

It would be great if someone already succeeded with the creation of a shared static library from a robovm project and could share the experience here or point me in the right direction to resolve the issue.

like image 717
wfrank Avatar asked Oct 21 '22 04:10

wfrank


1 Answers

As you mentioned, you probably haven't finished initialising robovm.

You'll need to create a method, say initRoboVM(), to somewhat mirror bc.c's main method. This will be called by your code when you want to initialise robovm. You'll need to pass the app path in, which you can hardcode when you're testing.

initRoboVM() will need some modifications, namely it should not call your Java app's main method, well, at least, that's what well behaving libraries should not do IMO. It should also not call rvmShutdown.

like image 63
user3161951 Avatar answered Oct 22 '22 18:10

user3161951