JNI and COM problem

From: Randy Roman (r.roman_at_uniserv.com.ph)
Date: 03/04/04


Date: 3 Mar 2004 19:49:45 -0800

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.



Relevant Pages

  • Re: Java programmer lured back by .Net (Questions)
    ... in .NET a form is simply a class so yes it could easily be placed into a DLL and then use Ngen to make a native image of it. ... Of course it learned a lot from Java, and improved upon many things which Java is slowly catching up on. ... As far as code security you're in the same boat as Java since it compiles down to MSIL instead of bytecode of which both can reverse engineered very easily. ... I would like to be able to place my executable on my remote server and then "load" the executables on demand from accross the internet - so that there are no executables on the local machine for prying eyes to reverse engineer. ...
    (microsoft.public.dotnet.distributed_apps)
  • Re: Java programmer lured back by .Net (Questions)
    ... in .NET a form is simply a class so yes it could easily be placed into a DLL and then use Ngen to make a native image of it. ... Of course it learned a lot from Java, and improved upon many things which Java is slowly catching up on. ... As far as code security you're in the same boat as Java since it compiles down to MSIL instead of bytecode of which both can reverse engineered very easily. ... My backend is pure Java running on Unix - but because SWING is so ...
    (microsoft.public.dotnet.distributed_apps)
  • Re: How to operate the ListCtl in a worker thread.
    ... The work is initiated from within uf2 via a call to an MFC C++ dll. ... Where does the "dialog_Handler" function reside..In worker thread or UI ... > cross-thread SendMessage are deeper than that. ... >>I had decided to use a shared memory between the two threads, that is, the ...
    (microsoft.public.vc.mfc)
  • Re: JNI EXCEPTION_ACCESS_VIOLATION
    ... I am not experienced in coding a dll and access it via ... Java, but, I would say to you that, if you do not mind, try to use the ... The code will crash when running under XP Service Pack 2 ... The code will NOT crash when running under Windows 2000 Service Pack 4 ...
    (comp.lang.java.programmer)
  • Re: How to operate the ListCtl in a worker thread.
    ... The app and DLL have common address space and can access the same memory, ... > messages to the MAIN GUI thread handle. ... > About the worker thread, ... > I had decided to use a shared memory between the two threads, that is, the ...
    (microsoft.public.vc.mfc)