Search code examples
javacomjacobcom4j

Connect 64bit Java with 32bit COM dll using Com4j or Jacob


I have the following configuration:

1) Windows 10 64-bit

2) An application that has only a 32-bit version and is available through COM.

I access the .dll file of the 32-bit application using the tlbimb.jar to generate the interfaces needed and I succeed.

Scenario 1: I try to access the 32-bit application using the Java 8 32-bit installation. I can invoke the methods through COM succesfully without any problem.

Scenario 2: I try to access the 32-bit application using a Java 8 64-bit installation. I get an error message:

Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153

I searched for the exceptin on Stackoverflow/Google and I have done the following:

1) Registered the application's dll using both Sys64WOW/regsvr32.exe and the System32/regsvr32.exe

2) Registered the com4j dll (both 32 and 64 bit) using both Sys64WOW/regsvr32.exe and the System32/regsvr32.exe

3) Copied the dlls in the Sys64WOW and System32 folders.

I have done all the above separatelly, checking all the possible combinations. The afortementioned error using 64-bit Java still exists.

I have tried using another bridge (Jacob). On 32-bit Java it succeeds, on 64-bit Java it fails.

I have a question for someone that might knows: Is there any way to connect an app that, as far as I can tell, offers only a Win32 COM dll[1], using any of the available Java/COM bridges and Java 64bit? Or simply 32-bit COM + 64-bit Java are not connectable?

[1]: I checked the OLE/COM Viewer and under the Type Library there's is only one entry "0 Win32 = , so I implied that this means there's no Win64 COM dll, right?


Solution

  • This won't work because the bitness of your client process and COM DLL don't match. When trying to create a new instance, CoCreateInstance tries to find related class information in the 64-bit hive of the registry. This fails because its actually located in the 32-bit hive, where you registered the DLL.

    To remedy this, you have the option of using a surrogate process, which allows your CoClass to be instantiated in a distinct native process. Your client can then communicate with the surrogate via IPC (see here for further info).

    As a quick start, you can mark your CoClass as a candidate for the default dllhost.exe surrogate process: OLE/COM Object Viewer (x86) as Admin > All Objects > [Your CoClass] > Implementation > Use Surrogate Process (leave path empty).

    If you intend to distribute your application, you may place this information in a REG script or import your DLL into a COM+ server application.