Alan Burlison 在 blog [JNI_OnUnload(): mostly useless
] 提到 JNI_Unload 這個 JNI call 搭配 JNIInvokeInterface 的 AttachCurrentThread call 造成非預期的現象。在 kaffe/include/jni.h 中，相關的定義如下：
extern JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM *, void *);
extern JNIEXPORT void JNICALL JNI_OnUnload (JavaVM *, void *);
jint (JNICALL *DestroyJavaVM) (JavaVM *);
jint (JNICALL *AttachCurrentThread) (JavaVM *, void **, void *);
jint (JNICALL *DetachCurrentThread) (JavaVM *);
jint (JNICALL *GetEnv) (JavaVM *, void **, jint);
jint (JNICALL *AttachCurrentThreadAsDaemon) (JavaVM *, void **, void *);
Alan Burlison 指出問題的癥結：
what was puzzling me was that although JNI_OnLoad() was being called OK, JNI_OnUnload() was never being called, and because the thread was attached to the JVM via a call to AttachCurrentThread(), the JVM would never exit as it still had an active thread. A simple workaround was to attach the thread to the JVM as a daemon thread using AttachCurrentThreadAsDaemon as daemon threads don't keep the JVM alive, but that still meant the DLL wasn't being cleaned up properly.
稍後他試著解決問題，過去可用 java.lang.System.runFinalizersOnExit() method，不過這已經 deprecated，他最後使用的解法如下：
In light of this it appears that although JNI_OnLoad() is useful, JNI_OnUnload() is less than useful. There is a workaround, which is to register a native exit callback using Runtime.addShutdownHook() and do the cleanup that way, but it's kind of broken that JNI_OnUnload() doesn't actually do what it is supposed to, and even more odd that the JNI documentation is completely silent as to why it doesn't actually work.
在 GNU Classpath (Kaffe 算是其「超集」) 中，package gnu.xml.libxmlj.util 用到這個技巧，可參閱 gnu/xml/libxmlj/util/XMLJ.java 在 initialization 的部份程式碼，其 JNI native impl 位於 native/jni/xmlj/xmlj_util.c。
由 jserv 發表於 February 19, 2006 04:01 PM