EZ Jcom
Java to COM/ActiveX Bridge

Accessing Java Classes From COM-Aware Languages

Overview

EZ JCom makes it very simple to access Java Classes from COM-aware languages such as C#, Visual Basic (VB.NET or earlier versions) and C++.

EZ JCom creates a COM (ActiveX) component from a specification of Java classes, fields and methods you provide. This COM component can be referenced by the COM-aware language such as Visual Basic or C#, by adding the COM component as a "Project Reference". The method calls and field accesses are then translated by EZ JCom to Java and sent to the underlying Java class(es.)

Constructors must be called!

When COM objects are instantiated, the underlying Java objects are not constructed at first. This is because of the following reasons:
  • There can be multiple constructors in Java, and it is not known in COM which constructor is to be used.
  • For static methods and fields, the Java object is not required. Pre-constructing the Java object may be undesirable if the programmer merely wishes to call a static method or access a static field.
For these reasons, after instantiating a COM object, one of its constructors (provided) must be called before calling any non-static methods or accessing any non-static fields.

A special constructor named ConstructByCasting is also provided to cast objects from one Java type to another. This can be used to cast objects to the expected Java type before calling methods. (If the object being cast is not cast-able to the given type, an exception will be thrown.)

Static Methods and Fields

Static methods and fields may be accessed without first having called a constructor. Note that if several COM objects of the same type have been instantiated, it does not matter which one is used to access a particular static method or field.

Arrays

Arrays of basic types (integers, shorts, bytes, floats, doubles, booleans and Strings) are supported, as well as array of COM objects that map Java classes.

In the .NET environment, all these are mapped to System.Array, and Intellisense will not show array types. Therefore the programmer must know the correct Java parameter expected. For instance, if the Java program expects an array of integers, an array declared as an array of integers must be passed. To pass an array of COM objects into Java, the array must be declared as an array of Variant's or an array of Object's.

Method and Field Names

The COM Interface Definition Language (IDL) does not support overloaded names, and does not distinguish between upper and lower case.

Therefore, EZ JCom will change conflicting or overloaded names. These names can be modified as desired, e.g. to better reflect the purpose of the method.

Parameter Names

Specially with the presence of Intellisense, parameter names should be meaningful.

Unfortunately, Java classes do not retain the original parameter names as specified originally by the programmer. Therefore EZ JCom allows a mechanism to specify the parameter names. While specifying the methods, the parameter names should be selected and changed to meaningful names.

Built-in Support for Java Types

Support is built-in for the Java primitive types. In addition, java.lang.String and java.util.Date are directly supported, as there are primitive mappings for these in COM.

Programmers can add support in EZ-JCom for any other desired Java classes. For instance, java.io.File may be added just like any user-defined class.

The Classpath

The COM component built by EZ JCom also includes a Java object. This object can be used to set the classpath at runtime, in case the environment variable CLASSPATH is not set as desired. If the classpath is changed via the Java object, this must be done before Java is loaded. Java will get loaded at first access of any Java class.

Visual Java display elements

EZ JCom can create visual COM controls from Java Panels or JPanels built using AWT or Swing. These visual COM controls can be embedded into forms etc. For this, make sure to select the "Allow embedding objects for visual display..." checkbox on the class properties.

Selecting Java Versions

By default, EZ JCom will pick the installed version of Java. But this behavior can be changed by setting the JvmPath property of the Java object to the desired JVM. This must be done before Java is loaded. Java will get loaded at first access of any Java class.

Receiving events from Java

Java events are sent on Java Interfaces. The interfaces specified to EZ JCom can be used for listening to events.

For receiving events on an interface, EZ JCom creates "Event Sink" classes corresponding to all interfaces.

Receiving events in Visual Basic

In order to listen for Java events from Visual Basic, use WithEvents, e.g.
    Public WithEvents MyEventSink As test.EventsInterface_EventSink
where "test" is the name of the library created by EZ JCom, and "EventsInterface" is the type of the Java events interface.

The Visual Basic IDE will then allow adding event handlers to MyEventSink.

The interface and event sinks object must also be initialized, the event sink must be connected to the interface, and the interface must be sent to the Java method that will register it for sending out events, e.g.

    Set MyEventSink = new test.EventsInterface_EventSink
    Set MyEvents = new test.EventsInterface
    myEvents.ConstructFromEventSink( MyEventSink )
    someObj = new test.SomeClass
    someObj.Construct
    someObj.registerListener( MyEvents )
In VB.NET, the "Set" should be dropped, and just
    MyEvents = new test.EventsInterface
should be used. In VB.NET, the "delegate" syntax can also be used for receiving the events, e.g.
    AddHandler myEvents.OnMyEvent, AddressOf myEventHandler

Receiving events in C#

Delegates are used to listen for Java events from C#, e.g.
    MyLib.myInterface_EventSink intfSink = new MyLib.myInterface_EventSink();
    intfSink.OnEvent +=
        new MyLib._IEventSink_TheEventHandler(myOnEvent);
where myOnEvent is the event handler method. Note that all the IDEs will fill in the delegate syntax and also add a method declaration -- for this, just enter the "+=" after the intf.OnEvent and when the IDE prompts, press TAB, and again when it prompts about creating the method.

The events interface should also be sent to the Java method that will regiter it for sending out events, e.g.

    MyLib.myInterface intf = new MyLib.myInterface();
    intf.ConstructFromEventSink( intfSink );
    someObject.registerListener( intf );

Passing Objects that implement Interfaces

Note that if you use ConstructByCasting on a Java interface object instead of using ConstructFromEventSink, it will not receive events. It can then be used as an argument to Java methods as any other Java objects. The events will not be coming back to C# or VB, because any events are now going directly into the Java object!

Java Exceptions

Uncaught Java exceptions are turned into COM exceptions. The exception object can be retrieved via the LastJavaException property of the Java object, if the Java class of the exception has been included in the list of classes given to EZ JCom.

The Technology

The technology for Java access is JNI (Java Native Interface.) However, using EZ JCom, the bridge can be generated very quickly, with no need for the programmer to spend time and effort with details of the underlying JNI. This saves not only much time and tedium, but also reduces the likelihood of various bugs, because JNI is a very low level technology where a number of low level bugs can easily creep in when it is handled manually.

Compared to all other methods of bridging Java to other languages, JNI is the fastest in terms of execution speed and therefore it is also the most scalable. Thus EZ JCom provides the best of both worlds, high-level control by the programmer, and a low-level high-performance bridge.