Search
 
     
   
   
 
  Java to IDL Mapping
   
 

The growing relevance of CORBA and OMG in the Information Technology world has made it an irresistible option to Software Developers. Infact, CORBA is the only system solution that supports all major languages and most major platforms. Sun underestimated this when they avoided CORBA altogether in their Java solution (More one this in the first article). Well, they had better reasons for doing so; they needed something simpler. It's was by now a public concern that CORBA was a tough solution, mainly due to the lack of platform support and surprising to me may people complain about the steep learning curve. Though I haven't said this before, OMG IDL is something I would like to see left out in the past but that would require of platform support. The pros of COBRA strongly favored it among the Software Developers community. The large number of CORBA servers that are deployed in the enterprise needed to be accommodated with RMI clients and newly developed RMI servers needed to be accommodated with the existing CORBA infrastructure.

Sun sure wanted something simple, they did consider that learning IDL would mean going the extra mile for most Java professionals. They wanted an Interface Definition Language for Java. This was pretty simple, they had interfaces in Java and more over, a well architected JVM that accommodated easy pass by value semantics (For more details of pass by value semantics, refer to the previous article). When RMI was introduced to the market Sun also bought along with it ease of programming, and good integration of ORB technologies to the JVM. I do like RMI, after all the power of Jini and Java Spaces, pretty advanced distributed technologies have this technology as its ORB. The people at Sun believed in making RMI the only solution for their distributed Java needs and making Java the defacto language for software development. This would never happen and resulted in Sun's inclusion of CORBA in their Java platform specification. But this meant that Sun had to do away with RMI altogether or augment RMI with the best known CORBA features like Transactions, Security, Fault Tolerance, Scalability and the sorts. They decided on the later solution.

People from IBM and Sun decided to work out a solution. They needed to integrate the RMI runtime with CORBA and still keep RMI like programming style. They came up with a simple solution, let the interface to the programmer still be RMI, and the messaging engine be IIOP. IIOP enables interoperability between different vendors ORBs. So, they decided to call it RMI over IIOP. However, this needed some changes in the tools that are to generate the middleware code - stubs and skeletons.

There were a lot of semantic differences between RMI and CORBA distribution concepts. However, the architectural pattern Broker along with the concepts of an ORB, stub, skeleton and servants is omnipresent in both the technologies. So, the mapping was not simple on CORBA, it needed some adjustments to IDL, some criticized for being too close to Java, like the valuetypes with methods, abstract valuetypes and abstract interfaces (read the previous article). One feature of RMI that CORBA lacked was pass by value semantics. RMI achieved it with the Java Serialization mechanism. With the inclusion of pass by value semantics to CORBA, this lack was addressed. Distributed garbage collection always was a contentious issue and would result in some very sticky situation. With RMI, you had true distributed garbage collection. Meaning, if the clients stopped using a RMI object, there was a corresponding decrease in the RMI objects reference count. In the case of CORBA, all objects are reference counted locally, meaning if the client drops the reference count, only the proxy reference count is reduced. As for the server side, there exist two concepts, the CORBA Object and the Servant. It's unto the Object Adapter to maintain this existence, and to terminate this association, and to remove the registered CORBA object. However, this is hidden behind the RMI/IIOP runtime.

One feature that I miss much is the casting operation. In RMI, a simple cast with the () [cast] operator would lead to the automatic download of the required stub. With plain CORBA you will not only need the stub code, but also need a CORBA cast operator. Well, does CORBA have a cast operator? It does have, but a very crude one. Remember, if a feature is not available with an Object System, you can achieve it with Objects. And this is exactly what CORBA has. Remember the Helper class and the narrow operation. It's just this feature that helps CORBA remain independent of language features (a good example reduced platform support for CORBA, which cannot be helped). With the integration of RMI and CORBA, well, you have the choice of downloading the stub remotely with the help of the codebase argument. This required of IIOP to be augmented with code downloading semantics. As of now, CORBA does not have any code downloading semantics. A simple solution would be to have the codebase attached to the IOR as a multicomponent profile (TAG_JAVA_CODEBASE).

The picture below will show how RMI/IIOP works from the architectural perspective. In the first picture you can replace the CORBA server side with an RMI server side seen in the second picture (the vice versa is also true).

Lets now look at the Java to IDL mapping in detail. To encourage convergence between the RMI and CORBA programming communities, it is important to define a solution that is both fully compatible with the current RMI semantics and fully compatible with OMG IDL, IIOP and CORBA Object Model. The subset of Java that meets these goals is referred to as RMI/IDL. A confirming RMI/IDL type is a Java type whose values may be transmitted across an RIM/IDL remote interface at run-time. A Java data type is a confirming RMI/IDL type if it is:

 

Lets now look at the Java to IDL mapping in detail. To encourage convergence between the RMI and CORBA programming communities, it is important to define a solution that is both fully compatible with the current RMI semantics and fully compatible with OMG IDL, IIOP and CORBA Object Model. The subset of Java that meets these goals is referred to as RMI/IDL. A confirming RMI/IDL type is a Java type whose values may be transmitted across an RIM/IDL remote interface at run-time. A Java data type is a confirming RMI/IDL type if it is:

One of the Java primitive types
These are: void, boolean, byte, char, short, int, float, double, long.

A conforming Remote Interface
A Java interface that can be invoked remotely should inherit from the java.rmi.Remote interface directly or indirectly and all its methods are to throw the java.rmi.RemoteException or its superclass. The arguments and the return type at runtime are to represent conforming RMI/IDL types. One interesting fact is that you can have method overloading. However, if the interface inherits from several interfaces, you cannot have conflicting names between the interfaces. You can also declare constants in the interfaces.

A conforming value type
An RMI/IDL value type represents a class whose values can be moved between systems. So rather than transmitting a reference between systems, the actual state of the object is transmitted between systems. This requires that the receiving system have an analogous class that can be used to hold the received value. A conforming RMI/IDL valuetype is a Java class that implements the java.io.Serializable or java.io.Externalizable interface and must not directly or indirectly implement the java.rmi.Remote interface. Methods and field names should not cause any collisions when mapped to IDL. A java.lang.String is also a conforming RMI/IDL valuetype but is mapped to an IDL string.

An Array of conforming RMI/IDL types
Arrays of conforming RMI/IDL types are also conforming RMI/IDL types.

A conforming exception type
An RMI/IDL exception type is a checked exception class and meets the RMI/IDL valuetype requirements.

A conforming CORBA Object Reference type
A conforming CORBA object reference type is either a Java interface org.omg.CORBA.Object or a Java interface that extends org.omg.CORBA.Object directly or indirectly and conforms to the rules specified in the Java Language Mapping.

A conforming IDL Entity type

A Java class is a conforming IDL entity type if it extends ormg.omg.CORBA.portable.IDLEntity and conforms to the rules specified in the Java Language Mapping and is not an OMG IDL user exception.

We start off the mapping of Java to IDL with naming conventions, then proceed to the primitive datatypes and end up with complex constructs. I would avoid some of the intricacies for the sake of brevity.

Naming Conventions
Packages are mapped directly to OMG IDL modules. Inner classes are mapped by appending two underscores after the outer class name followed by the inner class name. All overloaded methods are mangled with their respective arguments. This is a simple name-mangling scheme. For example the four overloaded Java methods:

   void hello();
   void hello( int x );
   void hello( int z[] );
   void hello( Object o );

Are mapped to the following OMG IDL methods:

   Void hello__();
   Void hello__long( in long x );
   Void hello__org_omg_boxedRMI_seq1_long( in
   ::org::omg::boxedRMI::seq1_long x );
   Void hello__java_lang_Object( in
   ::java::lang::_Object o );

Note
that any name clashes with built in Java names are avoided by prepending an underscore in front of the conflicting name as seen by the mapping of java.lang.Object.

Primitive Datatypes
The mappings for the Java void, boolean, short, int, long, float and double types are straight forward as they have exact OMG IDL analogues.

The 8 bit Java type byte is mapped to an 8 bit unsigned OMG IDL type octet. The mapping is bit-for-bit so that Java byte value "-1" is transmitted as GIOP octet "0xFF". Thus when using this mapping, we will preserve full value and sign information when using RMI/IDL between a Java client and a Java server over GIOP. A 16 bit Java Unicode char is mapped to an OMG IDL wchar type.


 

RMI/IDL Remote Interfaces
An RMI/IDL remote interface is mapped into an OMG IDL interface with the corresponding name in the OMG IDL module corresponding to the Java interface's package name. However, the java.rmi.Remote interface is mapped to an IDL Object (CORBA::Object), the base of all IDL interfaces.

   //IDL module java {
         module rmi {
         typedef Object Remote;
      };
   };


All methods of the form get and set are mapped to attributes and methods of the form get is mapped to a readonly attribute. Boolean properties like is is mapped to a boolean attribute. Compile time constants ("public final static") for primitive types and Strings are mapped to IDL constants.

RMI.IDL Value Types
RMI/IDL value classes that implement org.omg.CORBA.portable.IDLEntity and org.omg.CORBA.portable.ValueBase directly or indirectly are not mapped to OMG IDL because these Java classes correspond to existing OMG IDL value types that were mapped to Java using the OMG IDL to Java mapping.

If the RMI/IDL class extends some base class other than java.lang.Object or implement any other interface other than java.io.Serializable or java.io.Externalizable, and equivalent valuetype of interface is generated for this. Methods in the Java class is not required to be present in the generated IDL valuetype, mainly to avoid spaghetti effect of generating the entire Java Framework in IDL. As for constructors, they too are not required to be mapped to valuetype factories.

Any constants ("public static final") fields for primitive types and Strings are mapped to similarly named IDL constants in the target value type with the same values. All non-constant fields are mapped to state variables of a valuetype with corresponding access rights - public and private. The mapping of java.lang.String is special, its mapped to a ::CORBA::WstringValue. However, when mapping a constant string field, it's mapped to a wstring. So is the case for java.lang.Class, its mapped to ::javax::rmi::CORBA::ClassDesc.

   // Java
      package javax.rmi.CORBA;
      public class ClassDesc implements
      java.io.Serializable {
      private String repid;
      private String codebase;
   // space-separated
   list of URLs.
   };


RMI/IDL Arrays
An RMI/IDL Array is mapped to a "boxed" valuetype containing an IDL sequence. We use the syntax "valuetype xyz foo" as shorthand for defining a valuetype named "xyz" that contains a single field of type "foo".

Primitive OMG IDL types such as long, boolean, etc, are mapped directly into the ::org::omg::boxedRMI module. For other types, the module name to formed by taking the ::org::omg:boxedRMI prefix and then adding the type's existing module name to identify a sub-module. So the type ::a::b::c is mapped to ::org::omg::boxedRMI::a::b.

RMI/IDL Exceptions
OMG IDL does not allow subclassing of exception types. By contrast, Java programmers tend to make heavy use of exception subclassing, and the Java type system is used to distinguish different flavors of exceptions at run time. It is very common for a Java interface to say it raises a fairly generic exception but for implementations to throw more specific sub-types and for clients to make the Java instanceof operator to check for specific subtypes. In addition, RMI/IDL exceptions can e passed as normal valuetypes whereas OMG IDL exceptions can only be used in raises clause.

To allow full support for subclassing when communicating Java to Java we use a mapping where an RMI/IDL exception type is mapped to both a specific OMG IDL exception and to an OMG IDL valuetype that allows subclassing. The OMG IDL exception has a single field, which holds the corresponding value object. This solution allows RMI/IDL to support the normal idiomatic use of Java exceptions, while still being correctly mappable into OMG IDL.

CORBA Object Reference Types
A CORBA Object reference type is mapped directly to its corresponding OMG IDL interface or to Object if it is org.omg.CORBA.Object.

IDL Entity Types
An IDL entity type that is not a CORBA object reference type is mapped to a boxed value type containing the IDL entity type.

Non-conforming Classes and Interfaces
All Java interfaces that throw the java.rmi.RemoteException or a superclass of it are RMI/IDL abstract interfaces. All other Java interfaces are mapped to OMG IDL abstract value types with no data members. Non-conforming Java classes are mapped to OMG IDL abstract value types with no datamembers.

Abstract Interfaces
Java interfaces that do not extend java.rmi.Remote directly or indirectly and whose method definitions all throw java.rmi.RemoteException or a superclass are mapped to OMG IDL abstract interfaces. Java interfaces that do not extend the java.rmi.Remote directly or indirectly and have no methods are also mapped to OMG IDL abstract interfaces.

Implementation Classes
In general mapping RMI implementation classes to OMG IDL is not needed. However, if a given RMI implementation class implement multiple distinct RMI/IDL remote interfaces, then it is necessary to generate an OMG IDL type that represents the unification of the distinct RMI/IDL types. Any such composite RMI/IDL implementation class is mapped into an IMG IDL interface with the corresponding name. Each inherited RMI/IDL remote interface inherited by the Java implementation class is represented by an equivalent inherited interface in the OMG IDL interface. Inherited classes and inherited interfaces, which are not RMI/IDL remote interfaces, are ignored. At run time, any instance of the composite implementation class, must from a CORBA perspective, implement the corresponding composite OMG IDL interface. This implies, for example, they must return true to any calls of "is_a" on any of the OMG IDL interfaces associated with the distinct RMI/IDL interfaces.

Each and every technology has its fair share of criticisms, and so has RMI over IIOP. We did see that the addition of valuetypes, abstract valuetypes and abstract interfaces came under a lot of criticism from the purists. As for what has IIOP brought for RMI, many have their own arguments. One of the most pronounced advantages or IIOP is interoperability, and it does achieve interoperability in simple applications. But, when it came to Transactions and Security, it has a major problem when it came to interoperability between different vendor products. This is not an RMI/IIOP limitation but a general CORBA architecture limitation, which I am sure in time, will get addressed. As for inter ORB interoperability, you need a CORBA 2.3 ORB, where as a lot of existing legacy applications deployed in the enterprise are on CORBA 2.0. But the icing is the integration between J2EE and advanced CORBA - CCM that we shall see in detail in the coming issues.

   - Mr. Jacob Jose Cherakal - Software Architect,
 
     
     
Copyright © 2006 iCMG. All rights reserved.
Site Index | Contact Us | Legal & Privacy Policy