PRB: Java Threads Blocking when Accessing COM Objects

ID: Q232368


The information in this article applies to:
  • Microsoft virtual machine


SYMPTOMS

When using COM objects in a multi-threaded Java application, calls on apartment-threaded COM objects are serialized, even when the objects are created on their own threads. COM rules state that only one thread may exist in a Single Threaded Apartment (STA), and all calls to any object in that apartment must be serviced by the apartment's one and only thread.

This behavior, by design, serializes calls on objects in the apartment from other threads calling across apartment boundaries. However, in Java, even when apartment-model objects are created on their own Java threads and in what would seem to be their own individual STAs, calls on the objects from other threads are serialized and blocking may occur. In the Microsoft virtual machine, unless steps are taken to avoid the default behavior, calls on apartment-threaded objects are in fact being serviced by the same thread, regardless of the Java thread that created them.


CAUSE

This behavior saves work for you, the developer, because you don't need to implement a message loop to pump messages for STAs. When using only a few apartment-threaded COM objects, this behavior is a boon to the developer; however, when using many apartment-threaded objects, this behavior can be a significant performance hit. Fortunately, it is easy to override this default behavior.


RESOLUTION

In order to tell the Microsoft virtual machine that your Java thread is COM-friendly and that you have every intention of pumping messages for the STA in which it will reside, you use the ComLib.declareMessagePumpThread() method. See the example in the More Information section of this article.

Note that the call to ComLib.makeProxyRef() is the Java way to increment the reference count of the object, which is also be decremented during garbage collection of the Java Callable Wrapper (JCW), which is returned by this method.


STATUS

This behavior is by design.


MORE INFORMATION

This sample was taken directly from Chad Verbowski's excellent article, "Using COM Objects from Java."


package tutorial.sample;

public class STA extends Thread {
   /** 
    *Hosted COM object
    */ 
   private Object comObject = null;
   /**
    *   The returned object will be a proxy to the hosted COM object.
    *   The Microsoft VM will automatically take care of any thread
    *   marshaling requirements, allowing the returned object to be
    *   used like any other Java object.
    */ 
   public Object getHostedCOMObject( ){
      return com.ms.com.ComLib.makeProxyRef(comObject);
   }
   
   public void run(){
      com.ms.com.ComLib.declareMessagePumpThread();
      comObject = new SomeJCWClass();
      com.ms.win32.MSG msg = new com.ms.win32.MSG();
         while (com.ms.win32.User32.GetMessage(msg, 0, 0, 0)) {
            com.ms.win32.User32.TranslateMessage(msg);
              com.ms.win32.User32.DispatchMessage(msg);
      }
   }
} 


REFERENCES

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

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

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

For more information about Java-COM integration, consult the SDK for Java documentation and samples, and the Java Technologies' Technical Articles page.

Additional query words:

Keywords : kbCOMt kbJava kbJavaVM kbSDKJava kbVJ kbGrpJava
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbprb


Last Reviewed: November 16, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.