JNI:在線程或信號處理函數中訪問自定義類

在寫一個Tomcat應用,類須要被信號處理函數回調,但是在單獨的程序中測試沒用問題:
void OnSingalHandler(int sig)
{
  ...
  JNIEnv* env=NULL;	
  if (g_VM->AttachCurrentThread((void**)&env, NULL) != JNI_OK)
  {
	printf("AttachCurrentThread failed!\n");            
  }   	
 
  jclass cls = env->FindClass("nms/scada/Rtdb");
  jmethodID callback = env->GetStaticMethodID(cls,"RealDataChange","(Ljava/lang/String;)V"); 								
  env->CallStaticVoidMethod(cls,callback,CStr2Jstring(env,xmlDoc.GetDoc().c_str())); 
  
  g_VM->DetachCurrentThread();

  ...

}

    一切安好,但是移到Tomcat中時,FindClass就不工做了,不管如何返回都是NULL,看網上說是由於Tomcat的ClassLoader不同了,種種,試了很久未果。java

    後來發現即便是在Tomcat中,在JNI_OnLoad函數依然能夠用FindClass調用成功,惟獨在線程或者信號處理函數中有問題,或許是和AttachCurrentThread有關係吧。緩存

    因而想用全局變量緩存JNI_OnLoad中FindClass的結果,結果失敗。函數

後來又有人說全局變量緩存是能夠用的,不過要用NewGlobalRef建立全局對象引用,查了一下NewGlobalRef的定義:測試

   jobject NewGlobalRef(jobject obj);

根本就沒有給jclass用的啊,因而又開始亂找緣由,試着用Tomcat的ClassLoader什麼的緣由。最終也沒有成功。spa

又不甘心,查看jobject和jclass尼瑪,原來是一回事線程

     typedef jobject jclass;xml

好了,一用,妥妥的成功了。對象

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
    ...
    jclass classClass = env->FindClass("nms/scada/Rtdb");
    g_Class = (jclass)env->NewGlobalRef((jobject)classClass);
    ...
}

  完。string

相關文章
相關標籤/搜索