Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI: Calling GetStaticMethodID blows up

I'm writing some code to get a spawned thread to call a static Java method from C++.

The bits that call the method work fine if placed in a native call from Java, but not from a thread with an attached JNIEnv.

I've set a JavaVM* as follows:

jint JNI_OnLoad(JavaVM* jvm, void* reserved)
{
    LOGI("Setting Java Virtual Machine");

    ThreadJNIEnvironment::javaVM = jvm;

    return JNI_VERSION_1_6;
}

This does get called.

I then spawn another thread and from this thread I do the following:

JNIEnv* env;
jint ret = ThreadJNIEnvironment::javaVM->AttachCurrentThread(&env, NULL);

LOGI("AttachCurrentThread returned %d", ret);

jclass interfaceClass = env->FindClass("com/ecmsys/mcb/model/McbInterface");
jmethodID testMethod = env->GetStaticMethodID(interfaceClass, "Test", "()V");
env->CallStaticVoidMethod(interfaceClass, testMethod);

AttachCurrentThread returns 0.

GetStaticMethod blows up though with the following error:

Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1).....

I just can't see what I've done to upset it...oh wait...you can't access the Java application classes from a spawned thread without doing some set up...

jint JNI_OnLoad(JavaVM* jvm, void* reserved)
{
    LOGI("Setting Java Virtual Machine");
    ThreadJNIEnvironment::javaVM = jvm;

    JNIEnv* env;


    jvm->AttachCurrentThread(&env, NULL);
    jclass mcbInterface = env->FindClass("com/ecmsys/mcb/model/McbInterface");
    ThreadJNIEnvironment::interfaceClass = env->NewGlobalRef(mcbInterface);

    return JNI_VERSION_1_6;
} 

Then do this:

JNIEnv* env;
jint ret = ThreadJNIEnvironment::javaVM->AttachCurrentThread(&env, NULL);

LOGI("AttachCurrentThread retured %d", ret);

if(ThreadJNIEnvironment::interfaceClass)
{
    jmethodID testMethod = env-->GetStaticMethodID(static_cast<jclass>ThreadJNIEnvironment::interfaceClass), "Test", "()V");
    env->CallStaticVoidMethod(static_cast<jclass>(ThreadJNIEnvironment::interfaceClass), testMethod);
}


ThreadJNIEnvironment::javaVM->DetachCurrentThread();

You live and learn!

like image 679
freddy.smith Avatar asked Oct 06 '22 05:10

freddy.smith


1 Answers

Check for exceptions after looking up interfaceClass (env->ExceptionCheck()), or simply check that it's non-NULL. Most likely the class lookup is failing.

like image 158
technomage Avatar answered Oct 07 '22 20:10

technomage