Skip to main content

IDL-to-Java mapping: Part One

How discrete component interface definitions translate to Java elements

Dave Bartlett (dbartlett@pobox.com), Consultant, author, and lecturer, Freelance
Dave Bartlett lives in Berwyn, Pennsylvania, consulting, writing and teaching. He is the author of Hands-On CORBA with Java, a 5-day course presented via public sessions or in-house to organizations. Presently, Dave is working to turn the course material into the book Thinking in CORBA with Java. Dave has Masters degrees in Engineering and Business from Penn State. If you have questions or are interested in a specific topic, you can contact Dave at dbartlett@pobox.com.

Summary:  This article begins an examination of the IDL-to-Java mapping. This month's column looks at the basic data types, structure, and data transfer. Next month we will look at more complex types. Language mappings are not trivial and a sizable part of the CORBA Specification is devoted to the many languages mappings.

Date:  01 Oct 2000
Level:  Introductory
Activity:  3715 views
Comments:  

The CORBA Specification details the Interface Definition Language (IDL) and then details the mapping of IDL to several programming languages such as C, C++, ADA, COBOL, Lisp, Smalltalk, and Java. IDL is great for completely describing interfaces and all the operation parameters in detail. An IDL interface provides the information needed to develop clients that use the interface's operations and servers that implement the interface. However, clients and servers are not written in IDL, which is purely a descriptive language. Clients and servers are written in full-featured programming languages. An IDL language mapping should provide a consistent and portable framework for the interfaces defined. These mapped interfaces can then be implemented on the server side or called from the client side just as any other method. For each programming language used there must be a mapping that will easily translate the IDL concepts that have been defined. The mapping of an IDL concept to a client language construct will depend on the constructs and capabilities available in the programming language. For example, an IDL exception might be mapped to a structure in a language that has no notion of exception, or to an exception in a language that does offer exceptions. Each language's peculiarities and efficiencies must be accommodated.

Requirements for an IDL-to-programming-language mapping

All language mappings have approximately the same structure. They must define the means of expressing in the language:

  • All IDL basic data types
  • All IDL constructed data types
  • Constants defined in IDL
  • References to objects defined in IDL
  • Invocations of operations, including passing parameters and receiving results
  • Exceptions, including what happens when an operation raises an exception and how the exception parameters are accessed
  • Access to attributes
  • Signatures for the operations defined by the ORB, such as the dynamic invocation interface, the object adapters, and so on.

A complete language mapping will allow a programmer to have access to all ORB functionality in a way that is convenient for the particular programming language. To support source portability, all ORB implementations must support the same mapping for a particular language.

MotherIDL
Throughout this article we will use a file I call MotherIDL -- motheridl.idl. The IDL file can do it all and its purpose is just to look at and examine parts of the mapping. It may be a good idea to take a quick look at it so you can be familiar with it as we move through it.

In order to examine the mapping you will need an IDL-to-Java compiler. Every CORBA ORB comes with one or more IDL-to-some-language compiler. Most are for either C++ or Java programming language but you can find others as well. New additions can be found for Python and Delphi. For this column I will be using the JIDL that comes with the Orbacus ORB from Object Oriented Concepts, Inc. (see Resources) but you could use any IDL-to-Java compiler. Just make sure it is CORBA 2.3-compliant because your results could be substantially different if the compiler is working from an earlier version.

So the first task is to run the IDL-to-Java compiler against motheridl.idl.

jidl --output-dir . . \. . \. . MotherIDL.idl

This step magically gives you a whole host of Java files that reflect the IDL file as well as provide support and general CORBA plumbing.


IDL-to-Java library structure

The first mapping we should learn is the IDL module keyword to Java package keyword mapping. It is a simple and complete mapping. If there is a module keyword in an IDL file, your IDL-to-Java compiler will create a directory and library structure of Java classes utilizing the package keyword. (If you have any confusion at all about how the package keyword is used in Java programs, then you should brush up right now.) This mapping dictates much of the structure produced from the IDL and has a tremendous amount of influence on the IDL-to-Java mapping.

Using motheridl.idl as an example, you will see the following structure within the IDL file:

module corbasem {
  module gen {
    module motheridl {
      module holderexample {
      ...
      };
      module conflicts {
      ...
      };
      module basictypes {
      ...
      };
      module constructedtypes {
      ...
      };
      module holderexample2 {
      ...
      };
      module MI {
      ...
      };
      module MI2 {
      ...
      };
    };    
  };
};

This is translated into the following directory structure:

E:\_work\TICORBA\Projects\corbasem\gen\motheridl>dir /AD /S
 Volume in drive E has no label.
 Volume Serial Number is B415-7161

Directory of E:\_work\TICORBA\Projects\corbasem\

07/15/2000  01:41p      <DIR>          .
07/15/2000  01:41p      <DIR>          ..
               0 File(s)              0 bytes

Directory of E:\_work\TICORBA\Projects\corbasem\gen

07/15/2000  01:41p      <DIR>          .
07/15/2000  01:41p      <DIR>          ..
               0 File(s)              0 bytes

Directory of E:\_work\TICORBA\Projects\corbasem\gen\motheridl

07/15/2000  01:41p      <DIR>          .
07/15/2000  01:41p      <DIR>          ..
07/15/2000  01:41p      <DIR>          basictypes
07/15/2000  01:41p      <DIR>          conflicts
07/15/2000  01:41p      <DIR>          constructedtypes
07/15/2000  01:41p      <DIR>          holderexample
07/15/2000  01:41p      <DIR>          holderexample2
07/15/2000  01:41p      <DIR>          MI
07/15/2000  01:41p      <DIR>          MI2
               0 File(s)              0 bytes

One of the primary considerations in mapping IDL to Java elements is consistency. As with any library there has to be the stability associated with not removing existing methods when modifying a class in the library; the interface does not change. CORBA must go a step further because multiple ORB vendors will use this mapping to create libraries. We want consistency across ORB implementations; this means portability. Client or server code would not be portable if the IDL-to-Java mapping for ORB vendor A provided a UserException in package org.VendA.Excep, while vendor B provided the same UserException in package org.VendB.UtilTypes. Movement of the client or server to another ORB would require altering the code and recompiling. That is not why we have chosen CORBA! We want and demand portability; therefore the OMG specifies library structure.

In the Java programming language, it is the package keyword that brings together Java classes into the concept of a library and the control over who can access the components of that library. Our Java libraries will contain all the materials needed to build, in the Java programming language, what we have described in IDL. But to have portability from one vendor's libraries to the next vendor, the structure or packaging of the libraries must be specified and rigidly adhered to. Only in this manner can clients rely on the code and know that they won't have to rewrite code from one ORB vendor to the next.

The APIs specified in the portability section of the IDL-to-Java mapping provide the library structure and a minimal set of functionality to allow portable stubs and skeletons to be used with a Java ORB. Because Java classes are often downloaded and therefore come from sources that may be independent of an ORB vendor, the interoperability requirements for the Java programming language go beyond that of other languages. For these reasons, it is essential to define the interfaces that the stubs and skeletons use. If these structures were not defined then the use of a stub (or skeleton) would require one of two scenarios. The first would require the stub (or skeleton) to be generated by an IDL-to-Java compiler or similar tool provided by the ORB vendor (or is compatible with the ORB being used) so that the generated stub would fit the structure of the ORB vendor's libraries. The second scenario would require that the entire ORB runtime be downloaded with the stub or skeleton. We do not want either of these two scenarios. Ideally, we want to have IDL sent to a client or downloaded by the client and have them generate the stubs with the tool of their choice and connect to our server from their environment.

The Java language mapping is therefore highly dependent on a standard structure that is realized as a set of standard Java packages -- org.omg.*. An important piece of the IDL-to-Java mapping is a zip file containing PIDL, native types and ORB portability interfaces. This represents the definitive statement of the exact contents to the packages. However, as with everything in this industry, expect future versions of the IDL-to-Java mapping to change. Your understanding of the present mapping will ensure that you are alerted to any possible binary incompatibilities with future versions.


The basic data types

Mapping the basic types is rather straightforward. The table below shows just how cleanly the mapping occurs:

IDL Type

Java Type

Exceptions

boolean

Boolean

&nbsp;

char

Char

CORBA::DATA_CONVERSION

wchar

Char

CORBA::DATA_CONVERSION

octet

Byte

&nbsp;

string

java.lang.string

CORBA::MARSHAL, CORBA::DATA_CONVERSION

wstring

java.lang.string

CORBA::MARSHAL, CORBA::DATA_CONVERSION

short

Short

&nbsp;

unsigned short

Short

large number mismatch – test

long

Int

&nbsp;

unsigned long

Int

large number mismatch – test

long long

Long

&nbsp;

unsigned long long

Long

large number mismatch – test

float

Float

&nbsp;

double

Double

&nbsp;

long double

**unmapped

It is unclear at this time if this type will be added as a new primitive type or an addition to a library, for example java.math.BigFloat

To see a module that exercises all the basic types, check out the motheridl.idl example.

Integers
IDL signed integers represent no mapping problem for Java types. IDL short maps to the Java short, IDL long maps to the Java int and IDL long long maps to the Java long. This is very straightforward and should cause you few headaches.

Problems arise from the unsigned IDL types. The Java programming language does not have unsigned types and all integer types in the Java programming language are signed. In most situations this does not pose a problem but for the translation of an IDL unsigned integer type whose value falls inside the number range of its highest order bit there will be a mismatch. Without checking and correcting this mismatch, the Java side will present a negative number rather than a number at the upper end of that integer type's range.

For example, suppose we have an unsigned short returning from an IDL interface. The range of this type will be from 0 to 65535. The range for the signed Java short that will be receiving the value is -32768 to 32767. As you can see any value that falls between 32767 and 65535 will be mapped to a negative value in the Java short. This creates an impedance mismatch that must be tested for. This is true for unsigned short, unsigned long, and unsigned long long.

What implications does this create? First, I would say don't write new IDL definitions with unsigned integers. It just makes life easier. Secondly, if you are using or supporting existing IDL interfaces then you have to test the incoming unsigned integer and ensure it is handled correctly as a negative number in the Java program or is copied to a variable of a larger type capable of carrying the greater values.

Boolean and octet
These two IDL types provide a straightforward translation to Java types. The IDL boolean constants TRUE and FALSE are mapped to the corresponding Java boolean literals true and false.

The IDL type octet is an 8-bit quantity and it maps to the Java type byte.

Character and string types
Mapping characters poses some difficulties. First there is the character set being used and secondly the number of bits needed to carry the whole character set. Different languages have different characters and these differences are mapped by international standards organizations to character sets. These character sets represent mappings of a language letter or symbol to a number. The number of symbols in the language determines the bit width needed for the language. There are 8-bit character sets and 16-bit character sets.

IDL characters are 8-bit quantities representing elements of a character set while Java characters are 16-bit unsigned quantities representing Unicode characters. To enforce type-safety, the Java CORBA runtime asserts range validity of all Java chars mapped from IDL chars. Mapping in this direction does not pose a problem because we are going from an 8-bit value to a 16-bit value, and anything thrown at a Java program should be handled with no problem because there is plenty of space. However, when moving from a Java char to an IDL char it would be possible for that Java char to fall outside the range defined by the character set. In this case a CORBA::DATA_CONVERSION exception is thrown. The IDL wchar is simply the IDL type that maps to 16-bit character sets and it maps to the Java primitive type char. If the wchar falls outside the range defined by the character set, a CORBA::DATA_CONVERSION exception is thrown.

The IDL string is mapped to java.lang.String. Remember the IDL string is a sequence of char. This means that an IDL string must match the needs of the IDL char and the IDL sequence. Therefore, range checking for characters in the string as well as bounds checking of the string sequence is done at marshal time. Character range violations cause a CORBA::DATA_CONVERSION exception to be raised. Bounds violations cause a CORBA::BAD_PARAM exception to be raised. The exact same considerations and violations apply to the IDL wstring.

Floating-point types
Because both the OMG IDL and Java floating point types follow the IEEE 754-1985 Standard for Binary Floating Point Arithmetic, there are no problems with floating point conversions. However, there is no current support in the Java programming language for the IDL long double type. It is not clear at this point whether and when this type will be added either as a primitive type or as a new package in java.math.*, possibly as java.math.BigFloat. This is left for a future revision.

Validating the mapping
We can run our motheridl.idl file against the IDL-to-Java compiler that comes with the Orbacus orb: jidl --output-dir . . \. . \. . MotherIDL.idl

This gives us a Java Interface definition generated in the file UseAllTypesOperations.java.

This generated file validates our mapping. All the Java types are as we expected. The only wrinkle may be the types that reside in the inout and out parameter places -- they are all holders.


The holder class

Parameter passing is an interesting topic in any language and a fascinating problem when creating a language mapping from a language-independent architecture like OMG IDL. Java programs pass everything by value. This means that when you are passing primitives into a method, you get a local copy of the primitive. However, if the method parameter is a Java object, you do not pass the object but a reference to the object. Therefore, what is being passed is a copy of the reference, but that reference is being passed by value.

CORBA specifies in parameters and return types as call-by-value, while CORBA out is call-by-result and inout parameter types are passed call-by-value going in to the server and call-by-result when coming out. The out and inout parameter passing modes cannot be mapped directly into the Java parameter passing mechanism. Support for out and inout parameter passing modes requires the use of additional holder classes.

The IDL-to-Java mapping defines holder classes for all the IDL basic types as well as a specific format for user-defined types. The IDL-to-Java compiler will generate the holder classes for user-defined types, which are later used to implement these parameter modes in Java programs. The client creates and passes an instance of the appropriate holder Java class that is passed (by value in Java programs) for each IDL out or inout parameter. The contents of the holder instance (but not the instance itself) are modified by the invocation, and the client uses the (possibly) changed contents after the invocation returns.

An example of the IntHolder class is provided as part of the CORBA-Java library. Notice the public Java int value, as well as the value returned from the _type() method -- a long. Remember this is because the Java int maps to an IDL long.

Remember that holder classes are available for all of the basic IDL datatypes in the org.omg.CORBA package and holder classes are generated for all named user-defined IDL types except those defined by typedefs.

For user-defined IDL types, the holder class name is constructed by appending Holder to the mapped (Java) name of the type. For the basic IDL datatypes, the holder class name is the Java type name, with its initial letter capitalized, to which the datatype is mapped with an appended Holder (for example, IntHolder).

Each holder class has a constructor from an instance, a default constructor, and has a public instance member (value), which is the typed value. The default constructor sets the value field to the default value for the type as defined by the Java language: false for boolean, 0 for numeric and char types, null for strings, null for object references. To support portable stubs and skeletons, holder classes also implement the org.omg.CORBA.portable.Streamable interface.


Conclusion

That is only part one of the IDL-to-Java mapping. You should realize that programming CORBA-based applications and components with the Java programming language will require understanding the IDL-to-Java language mapping. The CORBA specification has many language mappings. Each one will weave its way through every aspect of your work. The portability of your code depends on the library structures you create as well as those of the OMG. The mapping serves the purpose of translating an interface definition to a language-specific implementation and that the beauty of that translation may be sacrificed for a more practical implementation. As we saw in the case of unsigned integers, there is a level of vigilance you must uphold to ensure your applications work as expected.

A language mapping is a sort of translation because you are taking one language and translating it into something that can work and be understood as an implementation. Just as some word phrases and structures do not translate well between spoken languages, some structures do not map easily and we must create solutions that, while they make the mapping more complex, make it easier to use in an implementation. Such is the case with the holder classes; they require some effort in the beginning to understand but over the long term provide general and consistent solution.

Next month we will delve deeper into the IDL-to-Java mapping. We will look at helper classes, more complex mappings like enum and union, and user-defined types.


Resources

About the author

Dave Bartlett

Dave Bartlett lives in Berwyn, Pennsylvania, consulting, writing and teaching. He is the author of Hands-On CORBA with Java, a 5-day course presented via public sessions or in-house to organizations. Presently, Dave is working to turn the course material into the book Thinking in CORBA with Java. Dave has Masters degrees in Engineering and Business from Penn State. If you have questions or are interested in a specific topic, you can contact Dave at dbartlett@pobox.com.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=86685
ArticleTitle=IDL-to-Java mapping: Part One
publish-date=10012000
author1-email=dbartlett@pobox.com
author1-email-cc=flanders@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers