BUG: Using Java Servers and DCOM (162164)



The information in this article applies to:

  • Microsoft Visual J++ 1.0
  • Microsoft Visual J++ 1.1
  • Microsoft SDK for Java 2.0
  • Microsoft SDK for Java 3.1
  • Microsoft SDK for Java 2.01
  • Microsoft SDK for Java 2.02
  • Microsoft SDK for Java 3.0

This article was previously published under Q162164

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 correctly on both the client and DCOM server computers. 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. Microsoft is researching this bug and will post new information in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

This article describes how to use the COMCallingJava sample that was included with Visual J++ 1.0 and 1.1 as a DCOM server.

First it is a good idea to 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. After you have the sample running typically, follow these steps to use the sample by means of 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 is included 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 later that discusses the use of DllSurrogate.

DCOM Client Steps

Follow these steps on the client computer so that you can use the COMCallingJava sample by means of DCOM:

  1. Run Javatlb (or JactiveX, then compile the resulting wrapper classes with Jvc.exe)on the client 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 computer.
  4. Delete the InprocServer32 key created in step 2.
More detailed information about these 4 steps:

  1. On the client side, you have 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 computer, 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 computer and can be safely deleted by deleting the euclid directory.

    NOTE: If you are using JActiveX.exe, you also have 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 computer to register the CEuclid class on the client:

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

  3. Make the correct registry entries that indicate that this COM object should be created on a separate computer, and specify the computer 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 will 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 must 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 its contents. Be very careful when manually editing the registry. Deleting the wrong key can make your system nonfunctional.
Note that all 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 by means of 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 computer to import the registry entries in the client computer 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 computer to change the DCOM server name after importing the reg file.

DCOM Server Steps

You have to follow these steps on the DCOM server computer to use the COMCallingJava sample by means of DCOM. Note that the Java VM must be installed on the Server computer to use a Java class file as a DCOM object. To locate and dowload the latest Java VM download visit the following Microsoft Web site:
  1. Copy the CEuclid.class file generated by Jvc.exe to the Server computers 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 computer 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 have to copy the CEuclid.class file that is generated by the Visual J++ compiler (Jvc.exe) to the Server computer trusted classpath - "\winnt\java\trustlib". Note that after building the COMCallingJava sample, there will be two CEuclid.class files on your build computer - 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 computer [ASCII 150] 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 computer 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 by means of 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- computer. Please note that Javareg.exe is a temporary DLL Surrogate which will be superceded in the near future by a DLL Surrogate built in 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 computer) 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 computer. Do not delete them (you could have deleted them on the client computer).
  3. Register the CEuclid.class file that you 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 must run REGEDIT again on the DCOM Server computer 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 the registry modifications can be done with a setup program, or by importing a .reg file. You still have 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 computer to enable the use of the COMCallingJava automation server by means of DCOM (Note that the explicit path to Javareg.exe in the LocalServer32 key below may have to be changed depending upon where you have copied Javareg.exe to on your DCOM Server computer):
<<<<<<<<<<<<<<<<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 computer and have the CEuclid Java COM object run on the DCOM server computer (Use the Windows NT Task Manager to view the startup and shutdown of the Javareg DLL surrogate on the Server computer).

REFERENCES

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

173790 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:

Modification Type:MinorLast Reviewed:11/17/2005
Keywords:kbArtTypeINF kbbug KB162164