Hello to all. I have a nagging problem concerning where to call
CoUninitialize() COM function. I realize that this may be more of a
C++/COM question rather than a Java question, but I just thought that
somebody with JNI/COM experience may be able to help me out. I already
posted a similar question in C++ groups but unluckily I haven't
received a reply. Here goes...
I have a JNI DLL that is statically linked to an MFC DLL. The MFC DLL
calls certain COM functions. The following is a snapshot of my MFC
DLL:
BOOL CCdmProxyApp::InitInstance() {
//////////////////////////////////////////////////
// COM library initialization and creates multithreaded apartment
HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(result)) {
bCoInitOK = FALSE;
return FALSE;
}
// OTHER CODES HERE...
}
// Exported functions may be called several times in different threads
from
// the Java side
CDM_PROXY_EXPORT LONG ExportedFunc() {
AFX_MANAGE_STATE(AfxGetStaticModuleState());
/* Initializes the COM library */
HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(result))
{
return -1L;
}
// DO SOMETHING HERE...
CoUninitialize();
return 1;
}
int CCdmProxyApp::ExitInstance() {
/* Closes the COM library */
if (bCoInitOK) {
// This function call hangs if the System.exit() is not
// called from the Java side. Determine what is the cause
of this
// bug.
CoUninitialize();
}
// Exit instance of this application.
return CWinApp::ExitInstance();
}
Basically, the call sequence from the Java side to the native side are
as follows:
1. Load native DLL via System.loadLibrary()
2. JNI DLL gets loaded along with MFC DLL
3. MFC DLL InitInstance() is invoked automatically and initializes the
COM library
4. Call any exported functions from the DLL which contains the pair of
CoInitializeEx and CoUninitialize pair (mandatory in my case)
5. Once java class exits, ExitInstance() will be invoked during the
unloading process of the DLL.
Upon reaching the last CoUninitialize() in the ExitInstance, the
program hangs. This happens if I do not call System.exit(0) in Java.
If I do, the unloading seems to proceed OK. However, I really cannot
call System.exit() because the class that loads the DLL is actually
loaded by a Servlet. Therefore I have no controll when the DLL should
actually be unloaded.
I suspect that it is not right to call the CoUninitialize inside
ExitInstance.
In summary, my questions are:
1. Why does the program hang if I do not call System.exit(0)?
2. Is there a way for me to ensure that I can call the outermost
CoUninitialize prior to unloading the DLL?
For example is it possible to create a worker thread in the Java side
where I can put the outermost CoInitialize() and CoUninitialize()
pair? My idea is to spawn a worker thread, initialize the COM library
at the start of the thread function, make it sleep indefinitely. When
the program exits, I would assume that the worker thread will be
terminated normally, and therefore the last CoUninitialize() function
can be called before the thread function exits. Hopefully this would
all happen before ExitInstance() ever gets called.
Thanks in advance.