Master of disguises: Making JavaBeans look like ActiveX controls

Learn how to make your JavaBeans available to Windows programmers using tools from Sun and Microsoft

Life's tough when you're trying to develop reusable software components. Often, the development tools your customers use dictate which development tools and architecture you choose. As a component developer, you may be attracted to the simple, object-oriented architecture of JavaBeans. However, there are a lot of Visual Basic (Visual C++, Delphi, etc.) developers who want ActiveX controls, not JavaBeans. Are you ready to forfeit these potential customers? Wouldn't it be great if you could write your components in Java and make them available to ActiveX control users? Well, you can. And in many cases, you won't even have to modify your existing Java code!

The right tool for the job: Choosing between the Sun and Microsoft tools

Currently, both Sun and Microsoft have bridging tools that are freely available for download: the Packager application from Sun and javareg from Microsoft (see Resources). Which one you choose will depend a lot on your personal tastes. Each has its strong and weak points. In general, users of your bridged JavaBeans won't see much difference between the two solutions. Both solutions utilize a Java virtual machine (VM) that is loaded as a dynamically linked library (DLL) into the client application or development tool. It's important to note that both solutions load only one instance of the VM per client. This allows an application to "connect" multiple ActiveX controls to each other, and know that that their underlying JavaBean instances are running in a shared VM.

Unfortunately, neither of the toolsets earns points for its robustness. Both do a rather poor job of helping you diagnose problems with your controls. However, I did find Sun's BeanBox testing tool helpful in validating JavaBeans prior to running either bridging tool. In addition, both tools suffer from a lack of good documentation (as if anything ever comes with good documentation, right?) Fortunately, Sun provides reasonably responsive e-mail support for its JavaBeans Bridge. While Microsoft's free support is limited, the Java-COM list server is a good place to look for answers specific to tools. (See Resources for information on how to access these support services.)

Sun's JavaBeans Bridge for ActiveX 1.0

The first tool we'll examine is the Packager application, which comes as part of Sun's JavaBeans Bridge for ActiveX. Packager allows you to:

  • Generate Windows-friendly event interfaces
  • Generate standard, easy-to-use registry files
  • Require separate jar files for ActiveX users

We'll examine each of these aspects in the following discussion.

Packager is a Java application that has both graphical and command-line interfaces. To use it, you place your JavaBean(s) in a jar file along with any supporting code or resources. Note that your beans must belong to a package other than the default package, otherwise the Packager will crash, leaving you with nothing but a cryptic error message about string parsing.

Packager's GUI guides you through the process of bridging your JavaBeans. You first select the jar file and JavaBean you wish to bridge, as well as the name for the ActiveX control and destination directory for the generated files. One nice feature is Packager's ability to "uncrack" Java events so they're delivered as their component parts -- much like events from "native" ActiveX controls -- rather than single event objects. The example below shows a typical Java event class:

public class GameEvent extends java.util.EventObject
{
    public GameEvent(Object source, int level, 
                     int numClicks, boolean won) {...}
}

If you don't select the uncrack option, a Visual Basic event handler method might look something like this:

Private Sub Blackout1_mouseClicked(ByVal GameEvent1 As Object)
    ' Get the number of clicks from the event 
    ' using the IDispatch interface
    Clicks.Caption = GameEvent1.getNumClicks
End Sub

Notice that the method receives the GameEvent instance as a generic Visual Basic Object type. Because Visual Basic supports late binding, the GameEvent.getNumClicks method can be invoked on the generic object. Behind the scenes, this call is passed to the Java object. (More on how this works later.) However, Visual Basic's name-completion capabilities will be unavailable to the user and invocation errors won't be detected until runtime.

Event handlers for uncracked events receive the event as a list of its component parts. Here's a handler, which has been uncracked, for the same event:

Private Sub Blackout1_mouseClicked(ByVal numClicks As Long, ByVal Level As Long, ByVal won As Boolean, ByVal source As Object)
    Clicks.Caption = numClicks
End Sub

Uncracking your events has two ramifications. First, because the event object is no longer passed into the event handler, any custom methods you've added to your event will be unavailable. Second, because event handler receives copies of the data in the event, it predicates that your event's fields are immutable.

After you select all the generation parameters, click on the Start Generation button to put Packager to work. Packager first generates adapter classes and adds them to your jar file. At this point your jar can only be used in an environment where the Sun ActiveX bridge classes (in the sun.beans.ole package) are available. If you want to distribute your JavaBeans to environments that will not have these classes, you'll need to ship a copy of the jar file that hasn't been run through the Packager.

Sun's Packager generates adapter classes for your JavaBean

Next, Packager generates type library (tlb) and registry (reg) files for the JavaBean. The registry file contains information about the ActiveX control, including the location of its type library and jar files. This file is loaded into the registry so that ActiveX client applications can access the control. Users of your controls can include the registry file with their applications and/or incorporate its contents in their application installation scripts.

The type library contains information about the COM (more on COM later) interface(s) supported by the control. Applications use this file to provide API information to the control user. Packager preserves your Java method parameter names, making the controls easier to use (Microsoft's javareg names parameters as Parameter0, Parameter1, etcetera). Although this file is binary, you can examine its contents with the OLE-COM Object Viewer that comes with Visual C++. You'll notice that this file looks a lot like any other type library. There's really nothing Java-specific about it.

Users of your control won't necessarily know they're using a JavaBean. It will appear along with the other ActiveX controls and have almost all the same characteristics found in controls written in other languages like Visual C++. It will, however, have one nifty addition. If you've gone to the trouble to write a customizer for your JavaBean, it will be available as a custom property page in ActiveX environments.

When a JavaBean/ActiveX control is loaded into a development tool or application, the registry information instructs the system to load the Java virtual machine as a dynamically-linked library (assuming it hasn't already been loaded) and create an instance of your JavaBean class. Subsequent method calls and events are passed between the application and the control via the adapter classes generated by the Packager.

When deployed, JavaBeans that have been bridged with the Packager will require the following items to be installed on your customer's machine:

  • The Java Development Kit (JDK) or Java Runtime Environment (JRE), version 1.1 or higher
  • The JavaBeans Bridge for ActiveX or JavaBeans Bridge for ActiveX Runtime
  • The jar file you ran through the Packager
  • The registry and type library files that were generated by the Packager

Note that the registry file contains some explicit directory information. You may need to modify the values to match the installation directories used on the customer's machine. Do this before the file is loaded into the registry.

Microsoft's Software Developer's Kit (SDK) for Java 3.0

Next we'll examine Microsoft's tool, javareg. Although javareg performs the same task as Sun's Packager, its approach is somewhat different. The javareg tool allows you to:

  • Register most Java classes a COM objects
  • Support low-level COM/DCOM as well as ActiveX
  • Require a special registration tool to be shipped with your controls

We'll examine each of these capabilities in detail in the following discussion.

javareg comes as part of Microsoft's SDK for Java. In addition to registering JavaBeans as ActiveX controls, it provides two capabilities currently unavailable from Sun's tools. First, it allows Java classes to be registered as standard COM/DCOM objects, as well as ActiveX controls. Second, it can register almost any Java class, regardless of whether or not it's a JavaBean. This supports low-level COM integration and also facilitates the implementation of user-defined types as JavaBean method parameters and return types.

In addition, the Microsoft SDK includes a package (com.ms.com) of classes that provide enhanced COM capabilities, including the ability to use COM objects written in other languages within Java code. If you're looking to integrate closely with COM, these capabilities will probably compel you to use javareg and the other tools in the SDK. This article, however, will focus on the ActiveX control registration, and leave the low-level COM discussion for another time.

Prior to using javareg, you should make sure that your JavaBean classes are accessible within the classpath. Next, you invoke javareg, from the command line, with parameters that specify how your JavaBean is to be registered:

javareg /register /control /codebase:. /class:blackout.Blackout /clsid:{3BFE1750-0C76-11d2-B0FA-00A024BA2CD9} /typelib:Blackout.tlb

In this example, the command-line arguments indicate that we're registering an ActiveX control from the blackout.Blackout Java class, and that the files can be located in the current directory. The CLSID parameter specifies a globally unique identifier (GUID) for the ActiveX control being registered. Most applications use the CLSID (rather than the name) to retrieve information about an ActiveX control. For this reason, control developers rarely change a control's CLSID. Providing the CLSID parameter allows you to ensure the same value is used any time the control is registered. If you don't specify the CLSID on the command line, javareg will create a new CLSID for the JavaBean. (Note: You can have explicit control of the CLSID with Sun's tools by editing the CLSID entry of the reg file generated by the Packager.)

Unlike the Sun tool, javareg doesn't generate adapter classes to implement bridging. Instead, Microsoft built the bridging smarts directly into its Java virtual machine. This eliminates the need to maintain a separate jar file for ActiveX installations. The javareg tool also bypasses generation of a registry file by directly updating the registry. This is unfortunate, as it limits your access to the information being inserted into the registry.

For example, while javareg does allow you to set the CLSID for your control, there are other registry identifiers, including one for the type library, that it generates every time it's run. Because Visual Basic applications use the type library identifier, the Visual Basic developer must repair applications that use a bridged control each time it is re-registered, even though the control itself may not have changed. In addition, customers of your controls will also need to incorporate javareg in the installation scripts for their applications. The good news is that many of the registry entries are boilerplate, so with a little effort you can solve these problems by generating your own reg file. However, it would be much nicer if the tool did this for you!

The javareg tool does, however, generate a type library. If you examine this file and the one generated by the Sun tool, you'll find the two are nearly identical. Inside the type library you'll find declarations for the public interface of your JavaBean, as well as the interface for objects that will receive events generated by your JavaBean. Both javareg and Sun's Packager will generate this information from your BeanInfo class if you created one for your JavaBean. Otherwise, introspection is used to generate the type library information.

Although javareg differs from Sun's Packager in the way it bridges your JavaBeans, usage of the controls is the same. The controls appear as normal ActiveX controls. When they're loaded into an application, the Microsoft Java VM is also loaded and an instance of the JavaBean is created.

When deployed, JavaBeans that have been bridged with javareg will require the following items to be installed on your customer's machine:

  • A recent version of the Microsoft Java virtual machine (msjava.dll)
  • The javareg.exe program from the Microsoft Java SDK
  • Your JavaBean and its supporting files

javareg will need to be run on the target machine. You may want to ship registration scripts and the type libraries, to ensure that controls are generated identically for all customers.

1 2 3 Page
Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more