在寫一個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