JNI,多线程和调用方法

时间:2012-02-03 12:50:18

标签: java c++ multithreading servlets java-native-interface

我正在尝试执行以下操作(不确定我是否遗漏了某些内容或者如果这是不可能的话):

我有一个Java类(在这种特殊情况下是一个Servlet),它调用一个本机方法。

在这个本机方法中,我正在生成一个新线程,并且在该线程中我想在该Java对象上调用一个方法。这甚至可能吗?

我在调用的原生方法(原始线程)中尝试的是记住JavaVM实例,以便稍后我可以将其他线程附加到它(似乎工作),并为jobject创建一个NewGlobal引用:

    JavaVM *vm;
env->GetJavaVM(&vm);

env->NewGlobalRef(jobj)

我不知道的是如何在另一个线程中检索jobject。如果我只是通过它崩溃,我假设因为非法线程访问。如果我为类创建一个新对象,我就不会拥有我需要的确切对象。

有什么想法吗?

谢谢你, 标记

某些附加代码(方法名称等模糊):

The method that is called from the servlet:

JNIEXPORT jstring JNICALL ABC (JNIEnv *env, jobject jobj, some more arguments
{
  JavaVM *vm;
  env->GetJavaVM(&vm);
  env->NewGlobalRef(jobj);

  // spawning new thread (I'm using boost libraries)
  boost::thread t = boost::thread(boost::bind(&XYZ::DEF, instance of XYZ, vm, &jobj);
  ...
}

void XYZ::DEF(JavaVM* vm, jobject* jobj)
{
    JNIEnv* env;
    vm->GetEnv( (void**)&env, JNI_VERSION_1_2);
    vm->AttachCurrentThread((void**)&env, NULL);
    ... then eventually calling another method, but still the same thread, where I'm doing this:

jobject bb = env->NewDirectByteBuffer(...,...); // this crashed when I just used the env from the original thread, seems to work since I'm attaching the second thread to the VM.

// it crashes somewhere during the following code:
jclass cls = env->GetObjectClass(jobj);
jmethodID mid = env->GetMethodID(cls, "callback", "(I)V");
env->CallVoidMethod(jobj, mid, 13);

崩溃产生类似这样的事情“JRE检测到致命错误......有问题的框架:V [libjvm.so + 0x3e9220] ......

1 个答案:

答案 0 :(得分:3)

你好像忽略了NewGlobalRef的结果。您必须在其他线程中使用其结果而不是原始jobj。