SUMMARY
Microsoft's VM for Java allows programmers to create two types of COM
objects with Java:
- COM objects that implement specific COM interfaces, either custom, dual,
or dispinterface.
- COM objects that implement only IDispatch and do not contain any type
information.
The first type of COM object is useful with strongly typed languages such
as C++ and Java. It is also useful when it is important for a COM object to
meet the "contractual obligation" of a specific COM interface. The creation
and use of this type of COM object is documented in samples included with
Visual J++.
The second type is useful with "late binding" environments like Microsoft
Visual Basic and the Microsoft scripting languages, VBScript and JScript.
This article covers the creation and use of this type of COM object.
MORE INFORMATION
In order to allow the use of Java objects in "late binding" environments
like Microsoft Visual Basic, VBScript, and JScript, the Microsoft VM for
Java implements IDispatch automatically for all Java objects. This feature
is called AutoIDispatch.
This means that Java programmers who need to use their Java objects only in
these environments no longer need to create interface definition files
(IDL/ODL). Also, tools like JAVATLB and JACTIVEX are no longer necessary
since the Java object does not implement any custom COM interfaces that are
defined in type libraries.
When a Java object with AutoIDispatch is used as a COM object, all of its
public methods and members are made available through the IDispatch
interface.
To implement a simple "late bound" automation object in Java using
AutoIDispatch, you would do the following:
- Implement a "standard" Java object with public members and methods and
compile it.
- Register it using JavaReg.
- Ensure that the Java class is visible in the class path by copying it to
the <windir>\java\lib directory.
Sample 1: Using a Java object from Visual Basic
A simple class could be defined as follows:
class Test
{
public String getString()
{
return "Hello!";
}
public int count = 10;
}
After compiling the class, copy the Test.class file to the
<windir>\java\lib directory so that this class is available to Java.
From a command prompt that has javareg.exe in its path, type the following:
javareg.exe /register /class:Test /progid:My.Test
Using Visual Basic 4.0 or greater, create a simple project with code
similar to the following:
Dim obj as Object
Set obj = CreateObject("My.Test")
MsgBox obj.getString ' This displays the string Hello
i = obj.count ' this assigns the value 10 to i
Visual Basic, the "late binding" client, automatically uses
IDispatch::GetIdsOfNames and IDispatch::Invoke (which the VM implements
automatically) to invoke the public method 'getString()' and accesses the
public member 'count'.
Sample 2: Using a Java object from Scripting
A simple applet class could be defined as follows:
import java.applet.*;
import java.awt.*;
class MyApplet extends Applet
{
// Notice that the member txt is public.
public TextArea txt = new TextArea();
public void init()
{
// Simply add the TextArea to the center
// of the Applet.
setLayout(new BorderLayout());
add("Center", txt);
}
}
Compile the source for MyApplet. Then create an HTML file as follows:
<html>
<HEAD>
<title>MyApplet</title>
</HEAD>
<BODY>
<hr>
<applet code=MyApplet id=app width=200 height=200>
</applet>
<hr>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
set txtobj = document.app.txt
txtobj.setText("Hello World!")
end sub
-->
</SCRIPT>
</BODY>
</html>
When Internet Explorer loads this Web page, the VBScript subroutine
'window_onLoad()' will be called. The text "Hello World!" gets placed in
the TextArea component on MyApplet. Note that we did not create a method on
the MyApplet class that specifically takes a String and calls
txt.setText(String). Instead, we made the txt object available as a member
of the MyApplet class by making it public. When the following script code
executes, the txt member of MyApplet becomes an AutoIDispatch COM object
itself.:
set txtobj = document.app.txt
At that point, all public members and methods on the txt object are
available to the script code. The next line actually calls the
setText(String) method of the TextArea component that is centered on the
applet:
txtobj.setText("Hello World!")
It is important to note here that the MyApplet object has not been
registered as a COM object on the client. It is just an Applet on a Web
page. But because the Microsoft VM for Java implements IDispatch
automatically for every Java object, scripting has full access to the
Applet.
OTHER INFORMATION
If for some reason, you need to turn off the AutoIDispatch feature for a
specific class, you can do so by having your class implement the
com.ms.com.NoAutoScripting interface. This interface does not contain any
methods. It just tells the VM not to expose IDispatch for any of the
instances of this class.
AutoIDispatch has the limitation that only the public methods on your class
can be invoked (via the IDispatch interface). Thus there is no need for
clients to become aware of the interfaces implemented by the server. The
limitation of AutoIDispatch is performance: Each method call (on a native
client) requires two round trips to the server(GetIdsOfNames and Invoke).
On a smart client (VB4) the results of GetIdsOfNames is cached so the two
roundtrips only occur on the first call to a particular method. In addition
there is slightly more overhead in calling/implementing Invoke vs. calling
a vtable based COM method directly. In cross-machine situations these
performance issues are reduced somewhat because of the latency caused by
the process/net boundaries.
Another limitation of AutoIDispatch is that the VM does not associate any
Type Library information with the COM object. So when a client calls
IDispatch::GetTypeInfo(), the Java COM object returns
TYPE_E_ELEMENTNOTFOUND. Again, AutoIDispatch is useful only for "late
bound" clients. Clients that require Type Library information cannot use
AutoIDispatch based Java COM objects.