|

|
Technical
Information
Integrating
Java and COM
|
|

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