BUG: Using Java Servers and DCOM

ID: Q162164

The information in this article applies to:

SYMPTOMS

There are various problems that you may experience when you try to use an Automation Server written in Java as a DCOM server. These can include hanging, timeouts, out of memory errors, interface not found errors, and other errors. These errors are generally caused by not registering the Java COM object properly on both the client and DCOM server machines. There are several known bugs with the javareg DCOM surrogate and the DCOM configuration utility DCOMCNFG that make it difficult to set up Java DCOM servers and clients.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

This article explains how to use the COMCallingJava sample shipped with Visual J++ 1.0 and 1.1 as a DCOM server.

First you should build the sample and run it as a conventional (InProcess) automation server. Do this by following the instructions outlined in the readme.html that is installed with the sample. Once you have the sample running normally, use the following steps to use the sample via DCOM.

NOTE: The DCOM support now in Windows 95 and Windows NT 4.0 with Service Pack 2 and Service Pack 3 supports surrogate as part of the system, so the surrogate support with JavaReg1.0 has been dropped. JavaReg2.0 is a new tool that ships with the Microsoft SDK for Java 2.0 and later. This tool fixes the bugs associated with JavaReg1.0 and supports remote access to a Java/COM object using the system provided surrogate process. There is also a Knowledge Base article listed in the REFERENCES section below that discusses the use of DllSurrogate.

DCOM Client Steps

Follow these steps on the client machine so that you can use the COMCallingJava sample via DCOM:

1. Run Javatlb (or JactiveX, then compile the resulting wrapper classes

   with jvc.exe)on the client in order to generate the registry entries for
   the COM Interfaces (the IGCD interface for this sample).

2. Register the Java COM object (CoClass) using Javareg.exe.

3. Run DCOMCNFG to select the DCOM Server machine.

4. Delete the InprocServer32 key created in step 2.

More detailed information on these 4 steps:

1. On the client side, you need to register both the CEuclid CoClass object

   and the IGCD interface. The IGCD interface can be registered by running
   JavaTLB.exe (or JActiveX.exe)on the euclid.tlb OLE type library file
   produced by building the ComCallingJava sample program as described in
   the readme.html supplied with the sample. To register the interfaces, on
   the client machine, run:

      JAVATLB EUCLID.TLB

   This registers the IGCD interface and produces a euclid package in
   \winnt\java\trustlib that contains the CEuclid.class and IGCD.class COM
   class wrapper files. This package is not required on the client machine
   and can be safely deleted by deleting the euclid directory.

   NOTE: If you are using JActiveX.exe, you'll also need to compile the
   resulting Java source files in the appropriate  <windir>\java\trustlib\ 
   directory.

2. Register the CEuclid COM object by using the javareg utility included
   with Visual J++. Run the following command line on the client machine
   to register the CEuclid class on the client:

      javareg /register /class:CEuclid /clsid:{33B0ECE2-E706-11cf-A0C2-
      00AA00A71DD8}

3. Make the proper registry entries that indicate that this COM object
   should be created on a seperate machine, and specify the machine on
   which it should be created. This can be done with the DCOMCNFG utility
   that is included with Windows NT 4.0 and the Windows 95 DCOM beta. Run
   the DCOMCNFG utility by clicking Run on the Start menu, typing in
   DCOMCNFG, and clicking OK. On the Applications tab of the DCOMCNFG
   utility, you should find an entry for CEuclid - "Java Class: CEuclid".
   Select this entry and click Properties. In the dialog box that appears,
   select the Location tab. In the Location tab, select the "Run
   application on the following computer" and type the name of the
   computer that will be the DCOM server.

4. You need to perform the final client-side step to work around a problem
   with the DCOMCNFG utility. The DCOMCNFG utility should, but does not,
   remove the InprocServer32 reg key that indicates that the Java COM
   object should be run as an In Process dll. You can manually delete this
   key by running REGEDIT and locating the
   HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8} folder.
   This folder should contain a subfolder called InprocServer32. Select
   the InprocServer32 subfolder and delete it and all of its contents. Be
   very careful when manually editing the registry. Deleting the wrong key
   can make your system nonfunctional.

Note that all of these registry modifications can be made in a setup program, or by importing a .reg file. Here is a sample reg file that you can use on the client platform to enable the use of the COMCallingJava automation server via DCOM:

<<<<<<<<<<<<<<<<start of client side reg file>>>>>>>>>>>>>>>>>

   REGEDIT4

   [HKEY_CLASSES_ROOT\AppID\{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}]
   @="Java Class: CEuclid"
   "RemoteServerName"="MYSERVER"

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}]
   @="Java Class: CEuclid"
   "AppID"="{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}"

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\Implemented Categories]

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\Implemented Categories\{BE0975F0-BBDD-11CF-97DF-
   00AA001F73C1}]

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-00AA00A71DD8}]
   @="IGCD"

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-
   00AA00A71DD8}\ProxyStubClsid]
   @="{00020420-0000-0000-C000-000000000046}"

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-
   00AA00A71DD8}\ProxyStubClsid32]
   @="{00020420-0000-0000-C000-000000000046}"
<<<<<<<<<<<<<<<<end of client side reg file>>>>>>>>>>>>>>>>

To use this file, copy the text to notepad and save it as CEuclidClient.reg. Double-click CEuclidClient.reg from the client machine to import the registry entries into the client machine registry. Note that this sample reg file has the "RemoteServerName" key set to "MYSERVER" (this entry is created by dcomcnfg). You can either change the MYSERVER text to the name of your DCOM server, or use the DCOMCNFG utility on the client machine to change the DCOM server name after importing the reg file.

DCOM Server Steps

You need to follow these steps on the DCOM server machine in order to use the COMCallingJava sample via DCOM. Note that the Java VM must be installed on the Server machine in order to use a Java class file as a DCOM object. The latest Java VM can be downloaded from http://www.microsoft.com/java.

1. Copy the CEuclid.class file generated by Jvc.exe to the Server machines

   java\trustlib directory.

2. Run JAVATLB (or JActiveX.exe, then compile the resulting wrapper classes
   with jvc.exe)on the Euclid.tlb file on the server machine to generate
   the Java COM wrapper files as well as register the Java COM objects COM
   Interfaces.

3. Run Javareg.exe with the /surrogate option to register the Java class
   file as a COM object, as well as create the registry entries needed
   to use Javareg.exe as the DLL Surrogate EXE.

4. Change the Threading Model registry key created in step 3 from "Both"
   to "Apartment" threading.

More detailed information on these 4 steps:

1. On the DCOM server, first you need to copy the CEuclid.class file

   that is generated by the Visual J++ compiler (Jvc.exe) to the Server
   machine trusted classpath - "\winnt\java\trustlib". Note that after
   building the COMCallingJava sample, there will be two CEuclid.class
   files on your build machine - One in the COMCallingJava project folder
   and one in the \windows\java\trustlib\euclid directory. The version of
   CEuclid.class in the project folder (the one generated by Jvc.exe) is
   the one that is the actual implementation of the Java COM object. This
   is the one that you want to copy to the \winnt\java\trustlib directory.
   The other version is generated by Javatlb.exe from the OLE type library
   (step 2) and contains special class file attributes that indicate to
   the VM that this java class is actually implemented in a COM/ActiveX
   object.

2. Copy the following files to the DCOM server machine ? Javatlb.exe,
   Javareg.exe, and Euclid.tlb. Javatlb.exe and Euclid.tlb are needed
   temporarily in order to register the Java COM object. Javareg.exe will
   be needed on the DCOM server machine semi-permanently. Javareg.exe, in
   addition to creating registry entries needed to register a Java COM
   object, can also be used as a "DLL Surrogate" executable. EXE servers
   are the only type that can be used via DCOM. The DLL Surrogate is an
   EXE that can be used to load an In-Process ActiveX/COM DLL (i.e., the
   Java VM) and marshall the COM calls cross-process and via DCOM, cross-
   machine. Please note that Javareg.exe is a temporary DLL Surrogate
   which will be superceded in the near future by a DLL Surrogate built
   into the operating system. This article will be updated with
   information on using the OS DLL Surrogate as soon as more information
   is available.

   Run Javatlb.exe (or JActiveX.exe, then compile the resulting wrapper
   classes with jvc.exe)on the Euclid.tlb type library:

      JAVATLB EUCLID.TLB

   This will (as was described for the client machine) generate a euclid
   Java package in the \winnt\java\trustlib directory. Note that the
   euclid package - the \winnt\java\trustlib\euclid\IGCD.class and
   \winnt\java\trustlib\euclid\CEuclid.class are required on the DCOM
   server machine. Do not delete them (you could have deleted them on the
   client machine).

3. Register the CEuclid.class file that we copied to the java\trustlib
   directory as a Java COM object. Note the addition of the /surrogate
   switch which will register Javareg.exe as the DLL Surrogate:

      javareg.exe /register /surrogate /class:CEuclid
      clsid:{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}

4. The registry entries created so that Javareg.exe can be run as a
   surrogate are not correct. You need to run REGEDIT again on the DCOM
   Server machine to change the threading model flag. Locate the
   InprocServer32 key:

      HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
      00AA00A71DD8}\InprocServer32

There should be a "ThreadingModel" string entry set to "Both". Double click on the "ThreadingModel" registry entry and change it's value data from "Both" to "Apartment".

Note that all of the registry modifications can be done with a setup program, or by importing a .reg file. You will still need to make sure that the CEuclid.class file that was created by Jvc.exe is copied to the java\trustlib directory (step 1). And that the euclid package created by JAVATLB.exe (or JActiveX.exe)exists. Here is a sample reg file that can be utilized on the DCOM server machine to enable the use of the COMCallingJava automation server via DCOM (Note that the explicit path to Javareg.exe in the LocalServer32 key below may need to be changed depending upon where you have copied Javareg.exe to on your DCOM Server machine):

<<<<<<<<<<<<<<<<start of server side reg file>>>>>>>>>>>>>>>>>>

   REGEDIT4

   [HKEY_CLASSES_ROOT\AppID\{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}]
   @="Java Class: CEuclid"

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}]
   @="Java Class: CEuclid"
   "AppID"="{33B0ECE2-E706-11cf-A0C2-00AA00A71DD8}"

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\Implemented Categories]

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\Implemented Categories\{BE0975F0-BBDD-11CF-97DF-
   00AA001F73C1}]

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\InprocServer32]
   @="msjava.dll"
   "ThreadingModel"="Apartment"
   "JavaClass"="CEuclid"

   [HKEY_CLASSES_ROOT\CLSID\{33B0ECE2-E706-11cf-A0C2-
   00AA00A71DD8}\LocalServer32]
   @="c:\\program files\\devstudio\\vj\\bin\\JAVAREG.EXE /clsid:{33B0ECE2-
   E706-11cf-A0C2-00AA00A71DD8} /surrogate"

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-00AA00A71DD8}]
   @="IGCD"

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-
   00AA00A71DD8}\ProxyStubClsid]
   @="{00020420-0000-0000-C000-000000000046}"

   [HKEY_CLASSES_ROOT\Interface\{33B0ECE1-E706-11CF-A0C2-
   00AA00A71DD8}\ProxyStubClsid32]
   @="{00020420-0000-0000-C000-000000000046}"
<<<<<<<<<<<<<<<<<<end of client side reg file>>>>>>>>>>>>>>>>>

You should now be able to run the Vbdriver.exe sample program installed with the COMCallingJava sample application on the client machine and have the CEuclid Java COM object run on the DCOM server machine (Use the Windows NT Task Manager to view the startup and shutdown of the Javareg DLL surrogate on the Server machine).

REFERENCES

For additional information on using the DllSurrogate support for Java/DCOM servers, please refer to the following Knowledge Base article:

   ARTICLE-ID:  Q173790
   TITLE:       HOWTO: Using DllSurrogate Support for Java/DCOM
                       servers.

For the latest Knowledge Base articles and other support information on Visual J++ and the SDK for Java, see the following page on the Microsoft Technical Support site:

   http://support.microsoft.com/support/visualj/ 
   http://support.microsoft.com/support/java/ 

Additional query words: DCOM Out of Memory

Keywords          : kbtool kbGenInfo kbVJ kbVJ100bug kbVJ110bug JCOM 
Version           : 1.0 1.1
Platform          : WINDOWS
Issue type        : kbbug

Last Reviewed: November 15, 1998