The
wonderful thing about COM is that it is language
neutral. However, it is reasonable to assume that its
creators at Redmond developed the standard having
Visual C++ and Visual Basic in mind. What is
incredible is the fact that a language like Java,
created by a direct competitor would mesh so well
with COM - better than any other available language.
Probably,
one reason for this unusual fit is because, Java can
support multiple interfaces. COM objects too support multiple
interfaces. This
and a few other features is what makes COM and Java a
natural pair.
COM
Interfaces are immutable. An Interface defines a
standard of communication between a client and its
server. By defining a set of methods, the interface
becomes the medium of communication between these two
objects. In reality, an interface just defines the
types of arguments and return values.
A COM
client directly calls functions provided by APIs in
the Operating System. The COM client should also
communicate with other COM objects using COM's
low-level binding protocol. C++ programmers can do
this with ease. However, Java programmers require a
mapping layer in the Java Virtual Machine (VM) and a
set of shim classes that provides for native calls to
the OS.
Microsoft's
implementation of the Java Virtual Machine integrates
Java objects and COM objects. One reason for this
integration is because, from a COM client's point of view, the Java VM makes
a Java Object appear to be another COM object. For example, if we were
talking of a Java applet, the MS VM would
automatically construct a dispinterface containing
all the applet's public methods. With other Java
objects, vtable interfaces are created. The MS VM
also provides an implementation of IDispatch for this Java
object. So, the object's methods are accessible to
the clients of this object. The MS VM also provides
an implementation of IUnknown for each Java
object, allowing clients to acquire pointers to other
interfaces the object supports. A Class Factory is also
implemented allowing a client to treat the Java
object like any other COM object. However, all this
is transparent to the Java programmer. (S)he just
creates and uses these objects as usual. All the
services necessary to make Java objects look like COM
objects are supplied transparently by the Microsoft's
Java VM.
From a Java object's point of view, an external
COM object looks exactly like a Java object. Again this
integration is achieved by the MS Java VM performing
the necessary translations to map between the two
kinds of objects.
Java makes the life of a COM programmer
relatively simple. For example, a programmer working
with COM objects in C++ must always be aware of Reference
Counting and ensure that Release() is called
whenever an interface pointer is no longer used.
Because Java supports Garbage Collection, this is not
a concern for Java programmers. When MS VM notices
that the "garbage" object being called is a
COM object, it simple calls Release() on the
object. Unlike C++ the creator of a Java COM client
need not keep track of which COM objects are no
longer needed and then release them.
When acquiring references to new
interfaces on an object, the MS VM hides calls to QueryInterface()
beneath the Java language's built-in
operators. The Java programmer writes the same code
to access a new interface regardless of whether that
interface is on a Java object or a COM object. In
fact, (s)he cannot even tell them apart. For a COM
object, however, the MS Java VM silently intercedes
calling QueryInterface() on the object
and returning the new interface pointer. Unlike C++
developers, COM programmers working in Java never
need to make explicit QueryInterface() calls.
To provide all the translations
required to map between COM and Java, MS Java VM
implementation relies on the information stored in a
COM object's type library. And to furthur integrate
Java into the COM world, MS offers Java class
libraries exposing key COM functions such as CoCreateInstance(), along with
access to monikers, Structured Storage and more.
Although neither Java nor COM were
designed with the other in mind, the two fit together
really well.
Shim classes that provide support for
native calls to the OS are built using the JavaTlb.exe or JCOM.exe utility that
ships with MS Java SDK. When you execute this library
from the command line and pass the type library of a
COM component, it produces the required shim class
files for the classes and interfaces that are
required. You can then import these into your classes
using the import keyword.