Accessing COM Objects from Java

In this section we describe how you can create an instance of a COM object, and use it from Java using J-Integra®. We also explain how to deal with new references to COM objects that are returned from method calls to COM objects:

You may wish to read through the documentation on the com2java tool prior to reading this section of the documentation.

Using Java classes generated from COM classes by com2java

For each COM Class that the com2java tool finds in a type library, it generates a Java class which can be used to access the COM Class. These generated Java classes have several constructors.:

The default constructor

The default constructor can be used to create an instance of a COM object on the local machine using the default authentication if it has been set, or using no authentication if no default has been defined.

In the case of the Shell class (see the com2java documentation for more details), the generated constructor looks like this:

/**
   * Constructs a Shell on the local host, with no authentication
   * @exception java.io.IOException if there are problems communicating via DCOM 
   * @exception java.net.UnknownHostException if the host can not be found 
   */
  public Shell() throws java.io.IOException, java.net.UnknownHostException {
    ...
  }

The following program creates an instance of the Shell COM Class on the local machine. It would fail if default authentication level were not set to none, and if access to the component were not granted to Everyone:

public class ShellExample {
  public static void main(java.lang.String[] args) throws Exception {
    try {
      Shell shell = new Shell();
      
      shell.minimizeAll(); // Minimizes all windows
    } finally {
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}
In this example, the domain, user and password specified as the default will be used:
public class ShellExample {
  public static void main(java.lang.String[] args) throws Exception {
    try {
      com.linar.jintegra.AuthInfo.setDefault("Domain", "User", "Password");
      Shell shell = new Shell();
      shell.minimizeAll(); // Minimizes all windows
    } finally {
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}

The second constructor (String host)

The second constructor can be used to create an instance of a COM object on a specific host using the default authentication if it has been set, or using no authentication if no default has been defined.

/**
   * Construct a Shell on specified host, with no authentication
   * @param     host  the host on which the object should be created
   * @exception java.io.IOException if there are problems communicating via DCOM 
   * @exception java.net.UnknownHostException if the host can not be found 
   */
  public Shell(String host) throws java.io.IOException, java.net.UnknownHostException { ...
  }
public class ShellExample {
  public static void main(java.lang.String[] args) throws Exception {
    try {
      com.linar.jintegra.AuthInfo.setDefault("Domain", "User", "Password");
      Shell shell = new Shell("mymachine.mycompany.com"); // Creates COM component on specified host
      shell.minimizeAll(); // Minimizes all windows
    } finally {
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}

The third constructor (AuthInfo authInfo)

The third constructor can be used to create an instance of a COM object on the local host using the specified authentication.

/**
   * Construct a Shell on local host, with specified authentication
   * @param     authInfo  information used to authenticate the local user to the remote host
   * @exception java.io.IOException if there are problems communicating via DCOM 
   * @exception java.net.UnknownHostException if the host can not be found 
   */
  public Shell(AuthInfo authInfo) throws java.io.IOException, java.net.UnknownHostException {
      ...
  }
public class ShellExample {
  public static void main(java.lang.String[] args) throws Exception {
    try {
      com.linar.jintegra.AuthInfo authInfo = new com.linar.jintegra.AuthInfo("Domain", "User", "Password");
      Shell shell = new Shell(authInfo); // Creates COM component on local host
      shell.minimizeAll(); // Minimizes all windows
    } finally {
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}

The fourth constructor (String host, AuthInfo authInfo)

The fourth constructor can be used to create an instance of a COM object on the specified host using the specified authentication.

/**
   * Construct a Shell on specified host, with specified authentication
   * @param     host  the host on which the object should be created
   * @param     authInfo  information used to authenticate the local user to the remote host
   * @exception java.io.IOException if there are problems communicating via DCOM 
   * @exception java.net.UnknownHostException if the host can not be found 
   */
  public Shell(String host, AuthInfo authInfo) throws java.io.IOException, java.net.UnknownHostException {
      ...
  }
public class ShellExample {
  public static void main(java.lang.String[] args) throws Exception {
    try {
      com.linar.jintegra.AuthInfo authInfo = new com.linar.jintegra.AuthInfo("Domain", "User", "Password");
      Shell shell = new Shell("myhost.mycompany.com", authInfo); // Creates COM component on specified host
      shell.minimizeAll(); // Minimizes all windows
    } finally {
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}

The final constructor (Object objRef)

This final constructor does not actually create a new instance of the COM Class. Instead, it can be used to access a reference to the COM class that was returned from another COM Class (from a method call, or via a property or event).

If a method or property returns a reference to a COM Class, then the com2java tool will automatically generate a method signature which returns the appropriate Java Class, if the returned COM Class is defined in the same type library.

For example the Excel type library (Excel8.olb) defines the Workbooks COM Interface, with the method Add which is defined like this in COM IDL:

[id(0x000000b5), helpcontext(0x000100b5)]
    HRESULT Add(
                    [in, optional] VARIANT Template, 
                    [in, lcid] long lcid, 
                    [out, retval] Workbook** RHS);

The locale identifier (lcid) is hidden from you by J-Integra®. Note that Workbook parameter is marked as being a return value. It is actually a COM Class, defined in the same type library as the Workbooks Interface. Because it is defined in the same type library, J-Integra® is able to generate the following method in the Workbooks Java interface that it generates:

/**
   * add. 
   *
   * @param     Template A Variant
   * @return    return value.  An reference to a Workbook
   * @exception java.io.IOException If there are communications problems.
   * @exception com.linar.jintegra.AutomationException If the remote server throws an exception.
   */
  public Workbook add  (
              Object Template) throws java.io.IOException, com.linar.jintegra.AutomationException;

So in this case, you don't need to do anything special to start working with the returned workbook.

If, however the type of the returned object were defined in another type library, J-Integra® would have generated the following method signature:

/**
   * add. 
   *
   * @param     Template A Variant
   * @return    return value.  An reference to a Workbook
   * @exception java.io.IOException If there are communications problems.
   * @exception com.linar.jintegra.AutomationException If the remote server throws an exception.
   */
  public Object add  (
              Object Template) throws java.io.IOException, com.linar.jintegra.AutomationException;

In this case, prior to being able to access the returned Workbook, you would need to create an instance of the Workbook Java class, using the final constructor:

Object wbObj = app.add(null);
  Workbook wb = new Workbook(wbObj);

Using Java interfaces and classes generated from COM interfaces by com2java

A method in a COM interface may return a reference to an object through a specific interface.

For example the Excel type library (Excel8.olb) defines the _Application COM Interface, with the method Add which is defined like this in COM IDL:

[id(0x0000023c), propget, helpcontext(0x0001023c)]
HRESULT Workbooks([out, retval] Workbooks** RHS);

The method returns a reference to an object that implements the Workbooks COM interface. Because the Workbooks interface is defined in the same type library as the _Application interface, the com2java tool generates the following method in the _Application Java interface it creates:

/**
   * getWorkbooks. 
   *
   * @return    return value.  An reference to a Workbooks
   * @exception java.io.IOException If there are communications problems.
   * @exception com.linar.jintegra.AutomationException If the remote server throws an exception.
   */
  public Workbooks getWorkbooks  () throws java.io.IOException, com.linar.jintegra.AutomationException;

It is revealing to look at the implementation of the method in the generated _ApplicationProxy Java class:

/**
   * getWorkbooks. 
   *
   * @return    return value.  An reference to a Workbooks
   * @exception java.io.IOException If there are communications problems.
   * @exception com.linar.jintegra.AutomationException If the remote server throws an exception.
   */
  public Workbooks getWorkbooks  () throws java.io.IOException, com.linar.jintegra.AutomationException{
    com.linar.jintegra.MarshalStream marshalStream = newMarshalStream("getWorkbooks");
    marshalStream = invoke("getWorkbooks", 52, marshalStream);
    Object res =  marshalStream.readDISPATCH("return value");
    Workbooks returnValue = res == null ? null : new WorkbooksProxy(res);
    checkException(marshalStream, marshalStream.readERROR("HRESULT"));
    return returnValue;
  }

As you can see, the method internally makes use of the generated WorkbooksProxy Java class. As mentioned above, the com2java tool generates the method with the Workbooks return type because the Workbooks interface is defined in the same type library as _Application.

If the Workbooks interface were defined in a different type library, J-Integra® would have generated the following code:

/**
   * getWorkbooks. 
   *
   * @return    return value.  An reference to a Workbooks
   * @exception java.io.IOException If there are communications problems.
   * @exception com.linar.jintegra.AutomationException If the remote server throws an exception.
   */
  public Object getWorkbooks  () throws java.io.IOException, com.linar.jintegra.AutomationException;

In this case, you would have to explicitly use the generated proxy class to access the returned Workbooks:

Object wbksObj = app.getWorkbooks();
  Workbooks workbooks = new WorkbooksProxy(wbObj);