Old Synopsis: destroyJavaVM() hangs waiting for AWT threads to die
We are developing a COM DLL in Visual C++ to plug into Microsoft Management Console (MMC). This DLL tries to invoke a Java method through JNI. If this method has NO gui action, then the DLL can successfully call destroyJavaVM() after the Java method invocation. But if there are any AWT components get shown in this method, even all components' dispose() methods have been called and reference is set to null, later on destroyJavaVM() will hang forever waiting for some AWT threads to die.
If the DLL doesn't call destroyJavaVM(), Windows will report memory leak.
This problem can't be solved by calling "System.exit()" from the Java method because it will result in killing the whole MMC process (we are writing DLL, not an application).
This problem can't be solved by using "exit hook". An exit hook method cannot unload JVM DLL on its own. If JVM DLL can't be unloaded, MMC can't exit.
The C code and Java code to produce this are attached. After native C code finished invoking on Prog.main(), it calls destroyJavaVM() and hangs forever.
The output of 'jni2.c' is:
C:> jni2
Before call java main() ...
Hello World from C!
destroying frame in java.main()
Thread 0(main) daemon status is false
Thread 1(AWT-EventQueue-0) daemon status is false
Thread 2(SunToolkit.PostEventQueue-0) daemon status is false
Thread 3(AWT-Windows) daemon status is false
Thread 4(Screen Updater) daemon status is false
After call java main() ...
Before destroy jvm ...
<<<hangs>>>>
We tested on both Windows NT 4.0 and Solaris JDK1.2.1.