Chad Verbowski
Software Design Engineer
Microsoft Corporation
January 1999
Download this document in Microsoft Word format (zipped, 26 KB)
Contents
Introduction
Java Objects in
COM
COM Objects in
Java
COM
Functionality in the Microsoft VM
Implementing a
Java/COM Object
Summary
Introduction
Sharing data across a network of computers in a bandwidth-efficient and
language-neutral manner is essential to developing a cohesive system for
doing business. Microsoft has worked hard to achieve a high degree of
integration between all of its products. Key to this success has been
developing a robust model that provides backward compatibility and
language independence. The Component Object Model (COM) was developed to
accomplish exactly these tasks and to provide a way to reuse and integrate
components at run time. This is a significant development considering that
most OO strategies target reusing components at compile time.
Using Java and COM, integration developers can employ Java's advantages
and develop components capable of interaction with operating systems,
applications, and services written in any COM-compliant language on any
platform. Because most of the Microsoft® Windows®
functionality is exposed through COM, and most Microsoft applications
provide COM interfaces to their object models, Java developers have
instant access to rich functionality.
The Microsoft virtual machine (Microsoft VM) provides automatic
mapping, allowing a Java object to be a COM object, and allowing any COM
object to be accessible as a Java object. This is a powerful feature that
makes all of the existing COM-based applications and services available to
Java and enables any existing Java objects to be used by other COM
supporting languages. The Microsoft VM contains functionality that
automatically converts a Java object to a COM component complete with
interfaces like IUnknown, IDispatch, IMarshal, and others used for
implementing Microsoft® ActiveX® Controls and COM
components. The Microsoft VM automatically handles object references,
cleanup, and interface queries for any COM object used in Java, whether
the component was written in Java or another COM-compliant language. These
features, along with garbage collection and the replacement of pointers
with references in the language, make Java ideal for many application
development projects. Java/COM development offers distinct advantages over
C implementations where the developer must contend with memory, threading,
and cleanup issues. This is also true for Microsoft® Visual
Basic® where developers can quickly implement an application
but want more control over how individual components behave.
Modern software projects typically contain an element of basic
development where only the features available in the language are used.
For example, for Java applications, this means that only the standard Java
packages and derivatives from them would be used. By packaging new
functionality as COM components, projects will benefit from distinct
encapsulation of capabilities and a clear path for future component
reuse.
It is quite common to use existing legacy code or third-party APIs to
reduce the development time and costs associated with a software project.
Integrating these components can be difficult because they could originate
from lots of vendors and may be implemented in different languages.
Services like Microsoft® Message Queue Server (MSMQ),
Microsoft® Transaction Server (MTS), Microsoft®
Active Directory™ (ADSI), Microsoft® Management Console (MMC),
and many facilities provided by the Windows operating system are exposed
through a set of COM-based objects. Java development projects, through
their COM APIs, can easily make use of the Microsoft services in addition
to any of the numerous COM components developed by third-party component
companies across the industry.
Some software projects benefit by integrating the functionality of
other applications. For example, features available through Microsoft SQL
Server, Microsoft Exchange, Microsoft Office, Internet Information Server
(IIS), Microsoft Site Server, and Microsoft Internet Explorer could all be
used in your software. All of these COM-based applications and many
third-party Windows-based applications expose object models for product
integration.
This document explains why Java is an excellent language for
COM-component development and why COM is the best method of developing
applications to integrate with third-party services and applications.
Back to Top
Java Objects in COM
Overview
Exposing a Java object as a COM component requires that the Java object
be contained inside a COM-compatible wrapper. The Microsoft VM does this
by using a COM-Callable Wrapper (CCW). It neutrally presents the Java
object for all other COM components and COM-compliant languages to use.
The Microsoft VM dynamically creates a CCW for the Java object when a COM
object is required. The CCW is essentially a generic COM object that has
its virtual table (vtable) of function pointers dynamically constructed to
support some default COM interfaces as well as any COM interfaces
implemented by the Java object. The default COM interfaces exposed for
every Java/COM object by the CCW allow Java objects to be used as
functional COM objects. For example, a Java object registered as a
Control will be exposed as an ActiveX component without additional
work. The CCW exposed for a Java object is capable of being aggregated,
but cannot aggregate another COM object. The Microsoft VM takes care of
storing the pointer to the outer COM object's IUnknown interface in the
CCW.
Details
The following table lists the default COM interfaces provided by the
CCW for Java objects.
| Interface |
Description |
| IUnknown |
The Microsoft VM handles the QueryInterface and reference
counts for all COM objects (Java implemented or not); there is no
need to expose any IUnknown functions to Java
developers. |
| IDispatch |
Provides Automation support. IDispatch assumes that the
underlying object is static. |
| IDispatchEx |
Extends IDispatch; provides Automation support for dynamic
languages such as scripting languages. IDispatchEx was developed to
support dynamic objects. |
| IProvideClassInfo |
Provides a single method for accessing the type information
for an object's coclass entry in its type library. |
| IProvideClassInfo2 |
Extends IProvideClassInfo with GetGUID, which returns the
object's outgoing IID for its default event set. |
| ISupportErrorInfo |
Ensures that error information can be correctly propagated up
the call chain. Automation objects that use the error handling
interfaces must implement this interface. |
| IMarshal |
Specifies how a COM object can be marshaled between processes
and remote computers. |
| IConnectionPointContainer |
Supports connection points for connection objects. Used to
locate a specific connection point. |
| IExternalConnection |
Manages a served object's count of marshaled (external)
connections. The COM object that implements such a count can detect
when it has no external connections and correctly shuts itself down.
This interface is used by the Microsoft VM for handling the
reference counts of COM objects. |
Overriding the functionality of most of these interfaces is done by
implementing them. The Java object's COM interface method implementations
are added to the vtable instead of the CCW's COM interface method
implementations. There are only three interfaces that cannot be
overridden: IUnknown, IExternalConnection, and ISupportErrorInfo. This
does not pose a problem to Java/COM developers. Because the Microsoft VM
deals with these interfaces, the developer is freed from tracking
reference counts, querying for interfaces, and propagating exceptions for
Automation objects.
When a Java object implements the java.io.Serializable,
java.io.Externalizable or com.ms.wfc.core.IComponent interfaces, the CCW
implements the following interfaces for that object. COM universally uses
these interfaces for serializing COM objects. This allows the Java/COM
object to be immediately available as data in an MSMQ message or used in
structured storage in conjunction with other COM or ActiveX objects in a
document.
| Interface |
Description |
| IPersist |
Has only GetClassID method; used to retrieve the CLSID of the
object for persisting. |
| IPersistStreamInit |
This interface is the same as the IPersistStream functions
and InitNew; it is used as a replacement for IPersistStream or for
persisting objects to a simple stream. |
| IPersistStorage |
Used to persist an object from a structured storage
object. |
A Java class that has been registered as a COM object and specified as
a Control (implying the object is an ActiveX Control) will cause
the CCW for that Java object to implement the interfaces as shown in the
following table.
| Interface |
Description |
| IOleControl |
Used for managing keyboard input. |
| IOleInPlaceActiveObject |
Allows communication with the outer frame. |
| IOleInPlaceObject |
Manages activation or deactivation of in-place
objects. |
| IOleObject |
Basic functionality for communicating with the
container. |
| IOleWindow |
Used to obtain windows and context-sensitive
help. |
| IPerPropertyBrowsing |
Used for exposing property information in an object
browser. |
| IViewObject |
Used for drawing the component. |
| IViewObject2 |
Used for drawing the
component. |
Any class registered as a Control extending an AWT component
that contains superclasses of java.awt.Component and contains the Java
interfaces com.ms.ui.IUIComponent and com.ms.object.ISiteable will have
the following COM interface implemented in its CCW.
| Interface |
Description |
| IObjectSafety |
Exposes functionality for Internet Explorer “Safe for
Scripting” and “Safe for Init” security features: 1) Safe for
Automation with untrusted scripts and Automation clients. 2) Safe
for initialization with untrusted data. 3) Safe for untrusted
scripts. |
Any class registered as a Control that contains the
com.ms.wfc.core.IComponent interface will have the interface automatically
implemented in its CCW.
| Interface |
Description |
| IDataObject |
Provides a basic data transfer mechanism, used with the
Clipboard and drag-and-drop. |
The component model of the underlying Java object contained in a CCW
will affect how the CCW creates the IDispatch(Ex), IProvideClassInfo(2),
and IConnectionPointContainer interfaces. Java objects that implement
com.ms.wfc.core.IComponent will have an IDispatch interface that contains
the methods and properties from the object's ClassInfo class. The
IConnectionPointContainer will have entries for each EventInfo contained
in the object's ClassInfo. The IProvideClassInfo(2) interfaces provide
type library information when it is first needed for a COM component by
dynamically creating the type library from the underlying WFC class's
ClassInfo. If the underlying Java object doesn't implement the
com.ms.wfc.core.IComponent interface, the JavaBeans Introspector is used
to gather information about the object's methods, properties, and events
for constructing the IDispatch(Ex), IProvideClassInfo(2), and
IConnectionPointContainer implementations.
Implementing the Java interface com.ms.com.NoAutoScripting will turn
this default behavior off, ensuring that this Java/COM object is not
automatically accessible for scripting. When a Java object implements this
interface, the Microsoft VM will not add the IDispatch(Ex),
IConnectionPointContainer, and IProvideClassInfo(2) interfaces to that
object's CCW.
Normally, a Java/COM object's CCW will aggregate the Free-Threaded
Marshaler (FTM). It is provided by COM to automatically marshal a COM
object to the correct thread when interface function calls are made. This
allows the COM object to be used from any thread without requiring the
call to be marshaled to the thread hosting the COM object. A Java/COM
object can turn this default behavior off by implementing the
com.ms.com.NoAutoMarshaling interface, which causes the CCW not to
aggregate the FTM. The CCW will effectively be created in the current
apartment, which may be either single-threaded (STA) or multi-threaded
(MTA).
Back to Top
COM Objects in Java
Overview
Ideally, a Java developer would like to use a COM object as if it were
a Java object. Accomplishing this requires that each COM object have a
Java wrapper for exposing its functionality. The Microsoft VM provides
this in the form of a Java-Callable Wrapper (JCW). A JCW is a Java class
that has some Microsoft-specific attributes that tell the Microsoft VM how
to map the Java object to the COM component that it represents. The
jactivex tool provided in the Microsoft SDK for Java can be used to
automatically generate JCW Java classes from any dynamic-link library
(.dll) file containing COM objects, or from any type library file produced
from a compiled COM object's Interface Definition Language (IDL)
definition. This tool provides a simple mechanism for generating classes
that Java developers can quickly and easily integrate with their project
to leverage existing COM facilities.
To create a JCW, compiler directives are added to regular Java source
files that specify how the Java object maps to the COM equivalent and vice
versa. By providing these mappings in the source file, a Java developer
can manipulate them to customize the Java representation of the COM object
to suit the particular application's needs. When the Microsoft Java
compiler compiles these source files, they are converted into Java class
attributes, which the Microsoft VM uses to map the COM object to the Java
object.
Details
The following table shows a list of the COM-specific directives that
the Microsoft Java compiler uses to create a JCW. For a complete
description of the directive parameters available for each directive and
how to use them, see the Compiler Directives
Reference.
| Directives |
Description |
| @com.class(GUID, security,
casting) |
Specifies that this Java object represents a COM coclass with
the given GUID, casting support, and Java security
requirements. |
| @com.interface(GUID, thread,
type) |
Indicates that this Java interface represents a COM interface
with the specified GUID, threading model, and types. |
| @com.method(dispid, vtable,
…) |
Marks the Java method as a COM interface method, which should
be exposed in the object’s vtable, dispatch table, or
neither. |
| @com.parameters |
Used to specify which parameters are in, out, or a return
value and how they should be mapped to COM and from COM to
Java. |
| @com.typeinfo |
Specifies additional information from the type library that
represents this COM object. |
| @com.transaction |
Indicates that the Microsoft Transaction Server can host COM
objects in a variety of transaction situations that can be indicated
with this directive. |
| @com.struct |
Specifies that the Java class will be a Java-Callable Data
Wrapper (JCDW). |
| @com.structmap |
Indicates how the field in a JCDW should map to COM and from
COM back to this field in Java. This directive can also be used to
custom marshal the data between Java and COM and to specify the
data's offset from the beginning of the
JCDW. |
A new instance of a COM object can be created in Java by simply
creating a new instance of a JCW Java class. The Microsoft VM creates the
COM object that it refers to in addition to tracking its references. A
QueryInterface is performed when a JCW is cast to an implemented COM
interface using the Java cast operation. When the Microsoft VM sees this
operation, it queries the underlying COM object for the interface
represented by the JCW being cast to. The resulting interface is returned
from the operation. The Java object can then call any methods on the
second COM interface as it would any other Java object. The Microsoft VM
caches the queried interfaces so that subsequent cast operations are
fast.
The key to integrating Java and COM, while maintaining consistency with
the Java programming model, is for the Microsoft VM to handle all garbage
collection of COM objects, and to map the QueryInterface calls to simple
casting operations. This functionality is directly related to how the COM
IUnknown interface behaves in Java. The Microsoft VM accomplishes
integration by not exposing any of the IUnknown methods to the Java
developer and by internally tracking the reference counts. As a result,
the developer is freed from possible bugs related to unbalanced reference
counts, and avoids the redundant operation of implementing each of the
IUnknown methods for each Java/COM object.
The Microsoft VM contains a JCDW classes for the COM VARIANT and
SAFEARRAY data types. Variants are objects that hold primitive data types,
IUnknown, or IDispatch references. Variants can be used as parameters
where multiple data types may be passed as parameters, and the actual data
type will be determined at run time. Variants are commonly used in Visual
Basic and in COM components for passing data of variable type through
Automation interfaces.
A SafeArray object is a COM data type that allows Visual Basic to
interact with COM components to pass around variable sized arrays.
SafeArrays contain Variant-compatible types and information that describes
the type of Variant contained, the starting position of the first element,
and the overall length of the SafeArray. The Variant and SafeArray JCDWs
contain Java methods that wrap the COM functions used to access the native
data types. This makes using Java Variants and SafeArrays intuitive for
developers and allows for painless interaction with Visual Basic through
COM.
Back to Top
COM Functionality in the Microsoft VM
The Microsoft VM handles the mapping of Java objects to CCWs and from
COM objects to JCWs. As such, this section provides details about these
two issues. It is interesting to see how the Microsoft VM handles creating
an instance of a COM object, and how it performs a QueryInterface call to
obtain the currently required interface.
CreateInstance
The create instance process described here covers a Java client
creating a new instance of a Java-implemented in-process COM object, which
is the superset of possible create instance scenarios. This section notes
which information is applicable to non-Java clients creating an instance
of a Java-implemented COM object, and for a Java client creating an
instance of a non-Java/COM object.
When the Java new operator is applied to a JCW Java object1,
the Microsoft VM analyzes the Java object’s class file for the
COM_Class_Type attribute generated by the @com.class directive. The
Microsoft VM uses the information from this attribute to determine the
CLSID of the underlying COM object. It also looks up the necessary
information for creating an instance of the COM object from the registry.
If the COM object to create is a Java-implemented COM object, the
InprocServer32 registry key has the value of the Microsoft VM,
Msjava.dll (the default in-process server for Java/COM objects that are
registered using the Javareg.exe tool from the Microsoft SDK for Java).
1 All COM objects are accessed from Java through JCWs, even
if they are implemented in Java.
The Msjava.dll implementation of DllGetClassObject initially goes to
the local registry and again looks under
HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\
for subkeys as shown in the following table.
| Subkey |
Description |
| JavaClass |
The value of this key will be a fully qualified class name
that represents the Java object to be exposed as a COM
object. |
| CodeBase |
This will be appended to the class path when the Java object
specified by the JavaClass key is created. If this key is not
present, only the Java system classes and those located in the
\Trustlib directory will be available in the class
path. |
| Control |
Marks the Java/COM object as being an ActiveX control. The
CCW provided for the Java object will implement additional
interfaces required by ActiveX
controls. |
The Microsoft VM provides a generic class factory for Java/COM objects
and initializes it with the information from the registry subkeys in the
previous table. Inside the Microsoft VM provided
IClassFactory::CreateInstance method, a CCW is created for the Java
object. The CCW then creates a COM vtable for each Java-implemented COM
interface. Each interface from the CCW is automatically supplied for the
COM object. If the Java/COM object created is being aggregated, a pointer
to the outer COM objects IUnknown interface is stored in the CCW. The
Microsoft VM uses CoCreateInstance to create COM objects that were not
implemented in Java.
The actual instance of the Java object contained within the CCW has not
yet been created. The actual Java object underlying the returned COM
object is created the first time an instance of it is required to answer a
COM function call. So, for IUnknown::QueryInterface to work, no Java
object instance is required. For an IDispatch method invocation to work,
however, a Java object instance would be created and maintained. The first
method that requires a Java object creates the instance.
Whenever a COM object is passed from the Microsoft VM to Java, the
Microsoft VM analyzes the Java type that the Java application expects. If
the return type is java.lang.Object and the COM object is actually a CCW,
the Java object contained in the CCW will be returned. Similarly, if the
return type is a COM interface JCW (implemented by the CCW's contained
Java object), the underlying Java object will be returned. Otherwise, the
COM object will be contained within an instance of the specified JCW
return type. The Microsoft VM provides a generic JCW (com.ms.com.CUnknown)
that can represent any COM object when a JCW is not specified as the
return type. A generic JCW can be created for any Java object at run time
by using com.ms.com.ComLib.makeProxyRef(Object o). The resulting
com.ms.com.CUnknown JCW object will refer to a CCW that wraps the
specified Java object.
QueryInterface
The Microsoft VM performs QueryInterface calls on COM objects. This
happens whenever a JCW representing a COM object or interface is cast to a
JCW representing a COM interface. This implementation allows COM objects
to naturally fit into Java development. Effectively, any COM object can be
queried for a COM interface in the same way that a Java object can be
queried for a Java interface.
Any Java object (pure or JCW) can be cast to an interface implemented
by the object's Java class of the object implements, such as
java.io.Serializable. If this cast can't succeed because the class doesn't
implement the interface, the Microsoft VM performs some COM-specific
operations. The VM ensures that the interface is a COM interface, and the
object to be cast is a JCW that supports dynamic casts (an option
specified in the JCW's @com.class directive). If these conditions are met,
the Microsoft VM queries the underlying COM object for the requested COM
interface.
Once the Microsoft VM has verified that the Java application is
attempting to perform a valid COM QueryInterface operation, it checks the
underlying COM object for a previous query for the interface that is being
casted to. It does this by looking in the JCW for the COM object's cache
of interfaces already returned to the Java client. If the COM interface is
in the cache, it is simply retrieved and returned. This table of
interfaces is essentially a hash table keyed by IID.
If the required interface is not already in the cache, the Microsoft VM
retrieves the underlying COM object from the JCW. QueryInterface is then
called on the CCW/COM object for the requested interface. If an interface
pointer is returned, it is stored in the JCW's cache and returned from the
casting operation. If the QueryInterface operation on the underlying COM
object fails, an error is returned to the Java application.
Back to Top
Implementing a Java/COM Object
Visual Basic programmers have had easy application development with COM
components through inclusion of the Automation interfaces in the COM
specification. Automation allows scripting languages (such as VBScript and
JavaScript) to interact with COM objects through the IDispatch interface
and late binding with the COM object functions. Automation in COM is
similar to manipulating Java objects through the reflection APIs.
Essentially, any method can be called on a COM object by specifying its
method name and parameters at run time. Further, this has the disadvantage
of being slower than vtable binding, as COM must obtain a pointer to the
method at run time, and there is no compile time assurance that the
correct method name and parameters are used. Automation-compatible
interfaces and methods are allowed to use only Automation-compatible types
as parameters and return values. A limited number of Automation-compatible
types exist, and there is no support for structures. The mapping of Java
primitives and objects to Automation types is outlined in the Microsoft
SDK for Java. The Microsoft VM provides automation interfaces for every
Java object in its CCW.
Automation interfaces are helpful when developing COM components that
will be used by Visual Basic or scripting languages. Vtable interfaces are
generally advantageous when developing components that will be used
primarily in Java and C. They are somewhat faster to use at run time and
use early binding techniques (programming errors are likely to be caught
at compile time rather than at run time). COM supports implementation of
an interface as both a Dispatch interface and a vtable interface. This is
known as a dual interface. These interfaces are supported in Java, by
means of specifying DUAL in the @com.class directive. For complete
information on the @com directives and their use, see the Compiler Directives
Reference.
Java is capable of implementing custom interfaces that contain methods
for passing standard Automation data types, as well as structures, custom
data types, and COM objects. The same is true for COM development in C.
The standard method for implementing custom interfaces in a COM object is
to define the object and all of its interfaces using IDL, and then
compiling it with a MIDL compiler. The Microsoft-provided MIDL compiler is
Midl.exe, available in the Platform SDK on the MSDN™ Library and with
Microsoft® Visual C++®. The MIDL compiler takes the
.idl file as input and generates a type library (.tlb file) and some C
code that implements a proxy and a stub for the custom object. Java
classes that represent the custom interfaces and the custom object can be
generated using Jactivex.exe provided in the SDK for Java. Jactivex takes
any standard type library file and generates corresponding .java files for
the COM objects, interfaces, and structures defined in the type library.
These Java files contain the correct @com directives for specifying the
.java files as JCWs.
A Java object can implement a COM interface in exactly the same way
that it implements a Java interface. The object being created does not
need @com directives when implementing the interface's methods. At run
time, the Microsoft VM uses the information from the implemented COM
interface wrapper's @com directives when the CCW is creating its vtable
for the Java object. Out-of-process and remote use of a Java/COM object
containing custom interfaces requires a proxy/stub DLL to be registered on
both the server and client computers. The proxy/stub DLL C source code is
generated by Midl.exe when compiling an IDL definition of the COM object.
The proxy/stub DLL contains the implementation of the proxy and stub COM
objects that COM uses to custom marshal client calls to the real COM
object containing the custom interfaces. Without the proxy/stub DLL,
remote creation and out-of-process creation of the COM object will fail
because the COM infrastructure will not know how to marshal the COM object
to the client.
To test a custom interface, register the Java/COM object using
Javareg.exe, and register the proxy/stub DLL file using Regsvr32.exe. Once
the registration is successful, use Oleview.exe (oleview is packaged with
Microsoft® Visual Studio® and the Platform SDK) to
create an instance of the Java/COM object. Then, examine the interfaces
that oleview displays for the Java/COM object. Along with the standard
interfaces exposed for a Java/COM object, the name of the custom interface
should also appear. Specify that the Java/COM object creation occurs as a
local server. This ensures that the proxy/stub DLL code is working
correctly. Oleview is an integral tool for COM development and is used to
verify COM objects to ensure that they are operating correctly. This is
the first place to look when debugging a COM application.
Custom Marshaling of Structures and Parameters
When specifying a structure or a parameter in a COM interface, it is
sometimes necessary to indicate to the Microsoft VM exactly how the
parameter or structure should be represented in native code. The
@com.structmap directive is used to specify how fields in a Java structure
are represented in native code. The @com.parameters directive is used to
specify how parameters are represented in native code. These directives
can indicate that the Java type should be marshaled by means of
user-defined methods when creating the native code representation, and the
Java representation from native code. To accomplish this task, the custom
marshaler must implement two methods, toExternal and toJava. For example,
the JCW representing the IPersistFile interface needs to specify the
String parameter in the Load method as custom marshaled. The custom
marshaler will be indicated in the parameter as a fully qualified Java
class. This is shown in the following example.
@com.parameters([in, type=CUSTOM,
customMarshal="com.ms.com.UniStringMarshaller"] pszFileName,
[in, type=u4] dwMode)
The Microsoft VM uses com.ms.com.UniStringMarshaller to marshal the
string that is passed as the pszFileName parameter.
com.ms.com.UniStringMarshaller must implement the toExternal and toJava
methods for performing the actual data marshaling.2 The
Microsoft VM calls toExternal and passes the memory address that should be
filled in with a native memory pointer to where the actual bytes
representing the string are located. The Microsoft VM also calls toJava
and passes the address in native memory where the bytes representing the
string are located. The toJava method is called to construct the Java
equivalent string from those bytes. The return value of toJava is assigned
to the parameter that was specified to have the custom marshaler.
2 Note that UniStringMarshaller also needs a
method called releaseExternal to free the string created by toExternal.
This is a requirement because cbByValSize is not defined by the class (the
marshaler will allocate a non-fixed size amount of memory).
Implementing Class Factories
Creating an instance of a COM object is accomplished through a class
factory, which is automatically provided for Java/COM objects by the
Microsoft VM. It is sometimes useful, however, to implement your own class
factory for a Java/COM object. A class factory contains a CreateInstance
method that handles requests for new instances of a particular COM object.
The class factory can then decide to return an instance that has already
been created if a single instance of the requested object is required.
Alternatively, a new instance can be created and returned. The class
factory, therefore, controls how an instance of a COM object is created,
the thread that the object is created on (important for single-threaded
objects), and which instance is returned. Fortunately, the Microsoft VM
supports implementing class factories in Java, which is accomplished in
the same way that a class factory would be developed in C by implementing
IClassFactory or IClassFactory2.
Jexegen.exe (from the Microsoft SDK for Java) can package the
Java-implemented class factory as an executable file that registers it
under the COM object's CLSID in the LocalServer32 registry key.
Then, any time an out-of-process request or remote request for the COM
object is received, the Java-implemented class factory will be used.
Back to Top
Summary
The essential components for Java/COM integration have been presented,
with emphasis on how COM components have been seamlessly integrated with
the Microsoft VM. COM development with Java is simpler and less
error-prone than implementing similar projects in C. The Microsoft VM
handles much of the tedious IUnknown work, and handles creating and
querying objects in an easy-to-use way. The Automation features available
to Visual Basic developers are also present for Java developers with the
option of delving deeper into the specifics of how COM objects are
implemented and used. As most Microsoft and third-party products and
services export object models for integration through COM interfaces, the
Microsoft VM's Java/COM integration provides the ideal environment for
developing COM components and applications.
Did you find this article useful? Gripes? Compliments? Suggestions
for other articles? Drop me a line at chadv@microsoft.com and let me
know.
Back to Top