Microsoft KB Archive/232368

= Java threads blocking when accessing COM objects =

Article ID: 232368

Article Last Modified on 6/14/2006

-

APPLIES TO


 * Microsoft Java Virtual Machine

-



This article was previously published under Q232368



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." To view this article, visit the following Microsoft Web site:

http://www.microsoft.com/mscorp/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); }  } }

