Java IDL: Java Meets CORBA - Part 1

Gopalan Suresh Raj

 

Distributed object computing extends an object-oriented programming system by allowing objects to be distributed across a heterogeneous network. Then each of these distributed object components interoperates as a unified whole. These objects may be distributed on different computers throughout a network and living within their own address space outside of an application, yet appear as though they were local to an application.

Three of the more popular distributed object paradigms are Microsoft's Distributed Component Object Model (DCOM), OMG's Common Object Request Broker Architecture (CORBA), and Sun’s Java/Remote Method Invocation (Java/RMI). In this article, you learn about the CORBA architecture and the mechanics of developing CORBA clients and servers.

The CORBA Distributed Computing Model

CORBA is a structural architecture designed to support heterogeneous object systems. CORBA achieves communication between different distributed objects while still allowing encapsulation and hiding of the internal object structure from external objects through Indirection. CORBA uses Indirection efficiently to achieve encapsulation preventing systematic recompilation.

CORBA defines a model that specifies interoperability between distributed objects on a network in a way that is transparent to the programmer. CORBA achieves this by defining ways for specifying the externally visible characteristics of a distributed object in a way that is implementation-independent.

This model is based on clients requesting the services from distributed objects or servers through a well-defined interface, by issuing requests to the objects in the form of events. An event carries information about an operation that needs to be performed, including the object name (called an object reference) of the service provider and the actual parameters, if any.

CORBA automatically handles a lot of network programming tasks, such as object registration, object location, object activation, request demultiplexing, frame and error-handling, marshaling, and operation dispatching.

CORBA objects are accessed through the use of an interface. OMG's Interface Definition Language (IDL, for short) is used to define interfaces, their attributes, methods, and parameters to those methods within the interface.

CORBA relies on a protocol called the Internet Inter-ORB Protocol (IIOP) for remoting objects. Everything in the CORBA architecture depends on an Object Request Broker (ORB). The ORB acts as a central Object Bus over which each CORBA object interacts transparently with other CORBA objects located either locally or remotely. Each CORBA Server Object has an interface and exposes a set of methods. To request a service, a CORBA client acquires an object reference to a CORBA server object. The client can now make method calls on the object reference as if the CORBA server object resided in the client's address space. The ORB is responsible for finding a CORBA object's implementation, preparing it to receive requests, communicating requests to it, and carrying the reply back to the client. A CORBA Object interacts with the ORB, either through the ORB interface or through an Object Adapter, which comes in two flavors: Basic Object Adapter (BOA) or Portable Object Adapter (POA).

Some of the benefits of CORBA include, but are not limited to, the following:

1. CORBA forces a separation of an object’s interface and its implementation.

2. CORBA’s support for reuse is inherent to the technology.

3. CORBA is scalable.

4. CORBA enforces transparency of platforms and languages.

5. CORBA provides interoperability.

6. CORBA abstracts network communication from the developer.

Because CORBA is just a specification, it can be used on diverse platforms, including Mainframes, UNIX, Windows, AS/400, and so forth as long as an ORB implementation exists for that platform. Currently, major ORB vendors like Inprise and Iona offer CORBA ORB implementations for numerous platforms.

The Object Management Architecture

OMG, the industry consortium that created the CORBA standard, defines two basic models on which CORBA and all its standard interfaces are based. They are

The Core Object Model defines concepts that facilitate distributed application development using the Object Request Broker (ORB). It defines a framework for refining the CORBA model to a concrete form. The Core Object Model is an abstract specification that does not attempt to detail the syntax of object interfaces or any other part of the ORB This model provides the basis for CORBA, but is more relevant to ORB designers and implementers than it is to application developers.

The Figure 1 shows the OMA Reference Model.

Figure 1: The Object Management architecture

The Reference Model defines a development model for CORBA and its standard interfaces through which developers can create and use frameworks, components, and objects. This model places the ORB at the center of a grouping of objects with standardized interfaces that provide support for application developers. In addition to the ORB, the Reference model identifies four groupings:

The CORBA 2.0 architecture

Figure 2 shows the CORBA 2.0 architecture. In CORBA, the IDL compiler generates type information for each method in an interface and stores it in the Interface Repository (IR). A client can thus query the IR to get run-time information about a particular interface and then use that information to create and invoke a method on the remote CORBA Server Object dynamically through the Dynamic Invocation Interface (DII). Similarly, on the server side, the Dynamic Skeleton Interface (DSI) enables a client to invoke an operation of a remote CORBA Server Object that has no compile time knowledge of the type of object it is implementing.

Figure 2: CORBA 2.0 architecture

The Object Request Broker (ORB)

The central component of CORBA is the Object Request Broker (ORB). This component provides all the communication infrastructure needed to identify and locate objects, handle connection management, and deliver data and request communication.

The Figure 3 shows a typical CORBA environment with the ORB facilitating communication between a Remote CORBA Server and a Client Application.

 

Figure 3: The Object Request Broker

One CORBA object never talks directly with another. Instead, the object requests for an interface to the ORB running on the local machine. The local ORB then passes the request to an ORB on the other machine. The remote ORB then locates the appropriate object and passes back an object reference to the requester.

The functions of the ORB are as follows:

Object Adapters

An Object Adapter is a server-side facility that provides a mechanism for the CORBA object implementations to communicate with the ORB and vice versa. An Object Adapter also extends the functionality of the ORB. An Object Adapter is layered on top of the ORB Core to provide an interface between the ORB and the object implementation. Object Adapters can also be used to provide specialized services optimized for a particular environment, platform, or object implementation.

Some of the services provided by an Object Adapter are

While many object adapter implementations may exist for unique situations, the CORBA specification only requires implementations to provide a Basic Object Adapter (BOA) or a Portable Object Adapter (POA) which is a portable version of the BOA.

Basic Object Adapter (BOA)

The BOA is a pseudo-object and is created by the ORB, but it is invoked like any other object. The BOA provides operations the CORBA Server Object implementations can access. It interfaces with the ORB Core and with the skeletons of your object server implementation classes.

A BOA may be required to perform two types of activations on behalf of a client’s request: implementation activation and object activation.

Implementation Activation: This occurs when the implementation for the target object is unavailable to handle the request. This requires the use of a daemon that can launch a Java VM with the server’s byte code. The information necessary to associate an object implementation with a Java class is stored in the Implementation Repository.

Object Activation: This occurs when the target object is unavailable to handle the request.

The BOA is mandated by CORBA 2.0, but was recently deprecated in favor of a Portable Object Adapter (POA). Even though vendors, to support existing implementations, may support the BOA, OMG will no longer update the BOA specifications.

Portable Object Adapter (POA)

The POA addresses many problems found in applying the BOA. It mandates additional functionality and is tightly specified to increase portability. With the POA API, the interfaces between the ORB and the object’s implementation have been standardized. Thus, CORBA services stand a fighting chance of being ORB-independent as well as interoperable.

The Implementation Repository

The Implementation Repository is an online database that contains information about the classes a server supports, the objects instantiated, and their IDs. Additional information about a specific ORB implementation may also sometimes be stored here.

The Dynamic Skeleton Interface (DSI)

For CORBA components that do not have an IDL-based compiled skeleton, the Dynamic Skeleton Interface (DSI) provides a runtime binding mechanism. The DSI determines the target object for which a message is meant by looking at the parameter values in an incoming message, so it can receive either static or dynamic client invocations. The DSI thus allows servers to dispatch client operation requests to objects that were not statically defined at compile time.

Interface Repository

The Interface Repository (IR) is an online database of metainformation about ORB object types. Metainformation stored for objects includes information about modules, interfaces, operations, attributes and exceptions.

The Dynamic Invocation Interface (DII)

During run time, the DII allows methods to be discovered dynamically so they can be invoked. Client programs can obtain information about an object's interface from the Interface Repository and dynamically construct requests to act on the object.

The Interface Definition Language (IDL)

Whenever a client needs some service from a remote distributed object, it invokes a method implemented by the remote object. The service the remote distributed object (server) provides is encapsulated as an object and the remote object's interface is described in an Interface Definition Language (IDL). The interfaces specified in the IDL file serve as a contract between a remote object server and its clients. Clients can thus interact with these remote object servers by invoking methods defined in the IDL. CORBA supports multiple inheritance at the IDL level and allows exceptions to be specified in the IDL definitions.

A typical CORBA IDL definition looks like Listing 1.

module SimpleStocks {
 interface StockMarket {
  float get_price( in string symbol );
 };
};

Listing 1: A typical CORBA IDL

The CORBA IDL file shows a StockMarket interface with a get_price() method. When an IDL compiler compiles this IDL file it generates files for stubs and skeletons.

IDL to Java Mapping

The highlights of the IDL to Java mapping are as follows:

Identifiers, Naming, and Scope

Except where a conflict would result with a Java reserved word, IDL names and identifiers are mapped directly to Java with no modification. Where a name or identifier in IDL exactly matches a Java reserved word, the collision is resolved by prepending an underscore (_) in the mapped name. For example:

// in IDL
interface synchronized {};

maps to

// generated Java
public class _synchronized {}

Depending upon the IDL construct, the mapping may require more than one uniquely named Java construct. When such a situation occurs, additional constructs are tagged on to the Java names like Helper, Holder or Package. In case any of these still conflicts with standard Java constructs, the collision resolution rule (_) applies.

Generated classes

In addition to the Java class that maps directly from an IDL construct, helper and holder classes may be generated to aid the developer in the use of the class.

Holder classes

Because all parameters are passed by value in Java, a method may change only the state of an object passed to it, not the reference to the object itself. To allow IDL types to be used with out and inout parameter passing modes, additional holder classes are required. The holder classes provide a level of indirection and are passed instead of the actual type. The client instantiates a holder object and passes it in the operation invocation. The server may then set or modify the value member of the holder object. Because the encapsulated actual object is modified without affecting the holder object reference itself, the semantics of out and inout parameters are supported. Holder classes are available for all the basic IDL datatypes in the org.omg.CORBA package and are generated for all named user-defined types, except those defined by nonconstructed type typedefs.

Helper classes

All user-defined IDL types have an additional helper Java class with the suffix Helper appended to the mapped type name. A helper class contains convenience and utility methods for operating on the associated object. The purpose of the helper class is to prevent bloating of the mapped classes with methods that may not be needed. The class provides methods for reading and writing the object to a stream, obtaining the object’s repopsitory identifier, and casting the object to/from a CORBA Any. The helper classes for mapped IDL interfaces also have the narrow() method defined, which is used to cast the object reference of org.omg.CORBA.Object to the base type of the helper.

Mapping for basic types

Table 1 shows the mapping of the CORBA basic types to the corresponding Java class or type.

Table 1: The Mapping for Basic Types

IDL Type Java Type Exceptions
boolean boolean CORBA::DATA_CONVERSION
char char  
wchar char  
octet byte  
string java.lang.String CORBA::MARSHAL
CORBA::DATA_CONVERSION
wstring java.lang.String CORBA::MARSHAL
short short  
unsigned short short  
long int  
unsigned long int  
long long long  
float float  
double double  

 

Mapping for enum

An IDL enumeration (enum) is mapped to a public Java final class. Each enumeration has two corresponding static class constants: one is a Java int named with a prepended underscore to the element identifier and the other is an instance of the mapped final class with the same name as the element that represents the element’s value.

// in IDL
enum TrafficLight {red, yellow, green};

maps to

// generated Java
final public class TrafficLight {
 
final public static int _red = 0;
 
final public static int _yellow= 1;
 
final public static int _green = 2;

 
final public static TrafficLight red = new TrafficLight(_red);
 
final public static TrafficLight yellow= new TrafficLight(_yellow);
 
final public static TrafficLight green= new TrafficLight(_green);

 
public int value() {....}

....
}

Mapping for struct

An IDL struct maps to a final Java class containing one instance variable for each structure field. The class name is the same as the IDL structure name. Two constructors are provided: one takes the fields of the structure as arguments to initialize the instance variables and the other is a null constructor that initializes the instance variables to null or zero.

Mapping for union

An IDL union is mapped to a final Java class that has the following characteristics:

Mapping for ordered collections

CORBA provides two types of ordered collections: sequences and array. A sequence maps to a single dimensional Java array, which may be either bounded or unbounded. An IDL array is a multidimensional array whose size, in each dimension, must be fixed at compile time.

Mapping for attributes and operations

Attributes are mapped to a pair of overloaded Java accessors and mutator methods. These methods have the same name as the IDL attribute and differ only in their signature. No mutator method exists for IDL read-only attributes.

Parameter-passing modes

IDL in parameters, which implement call-by-value semantics, are mapped to normal Java actual parameters. The results of IDL operations are returned as the result of the corresponding Java method.

IDL out and inout parameters, which implement call-by-result and call-by-value/result semantics, cannot be mapped directly into the Java parameter-passing mechanism. This mapping defines additional holder classes for all the IDL basic and user-defined types used to implement these parameter modes in Java.

Table 2 shows the mapping of IDL type to Java for the different parameter modes.

Table 2: Mapping of CORBA IDL to Java for different parameter modes

IDL Type In Mapping In/out Mapping Return Mapping
boolean boolean BooleanHolder Boolean
char char CharHolder Char
wchar char CharHolder Char
octet byte ByteHolder Byte
string Java.lang.String StringHolder Java.lang.String
Wstring Java.lang.String StringHolder Java.lang.String
short short ShortHolder Short
Unsigned short short ShortHolder short
long int IntHolder Int
Unsigned long int IntHolder int
Long long long LongHolder Long
Unsigned long long long LongHolder long
float float FloatHolder Float
Double double DoubleHolder double
Enum <enum>object < enum >Holder < enum >object
Struct <struct>object < struct >Holder < struct >object
Union <union>object <union>Holder <union>object
Sequence <sequence>object <sequence>Holder <sequence>object
Array <array>object <array>Holder <array>object
Any Any AnyHolder Any
interface <interface>object reference <interface>Holder <interface>object reference

 

Mapping for user-defined exceptions

A user-defined exception is mapped to a final Java class that extends org.omg.CORBA.UserException. The UserException class extends the standard org.omg.CORBAexception class. The mapping is identical to the IDL struct type, including generated Holder and Helper classes.

Mapping for system exceptions

The standard IDL system exceptions are mapped to final Java classes that extend org.omg.CORBA.SystemException and provide access to the IDL major and minor exception code, as well as a string describing the reason for the exception. Instantiating org.omg.CORBA.SystemException is impossible. Only classes that extend it can be instantiated.

Developing CORBA Servers and Clients

When developing distributed applications for CORBA using the Java IDL, you first identify the objects required by the application. Figure 4 denotes the Java IDL development lifecycle.

Figure 4: Java IDL Development Lifecycle

You are usually required to follow these steps:

1. Write a specification for each object using the IDL.

2. Use the IDL compiler to generate the client stub code and server skeleton code.

3. Write the client application code.

4. Write the server object code.

5. Compile the client and server code.

6. Start the server.

7. Run the client application.

Before developing CORBA servers and clients, make sure you have Java 1.2 and the idltojava compiler installed on your machine. The JDK provides the API and ORB needed to enable CORBA-based distributed object interaction. The idltojava compiler uses the IDL-to-Java mapping to convert IDL interface definitions to corresponding Java interfaces, classes, and methods, which you can then use to implement your client and server code.

Also ensure your Path and Environment variables conform to what is specified in the JDK installation docs. For more information about setting up these environment variables, see the Java JDK 1.2 Installation Guide.

You can always refer to my Homepage at http://www.execpc.com/~gopalan for more CORBA source code. Another good resource is the comp-object-corba@omg.org mailing list from OMG. You can get the CORBA specs from http://www.omg.org.

Go to Part 2 of this article

click here to go to
My CORBA HomePage...

 

About the Author...
Gopalan Suresh Raj is a Software Architect, Developer and an active Author. He is contributing author to a couple of books "Enterprise Java Computing-Applications and Architecture" and "The Awesome Power of JavaBeans". His expertise spans enterprise component architectures and distributed object computing. Visit him at his Web Cornucopia© site (http://www.execpc.com/~gopalan) or mail him at gopalan@execpc.com.

Go to the Component Engineering Cornucopia page

This site was developed and is maintained by Gopalan Suresh Raj

This page has been visited times since September 21,1998.

Last Updated : Dec 19, '98

If you have any questions, comments, or problems regarding this site, please write to me I would love to hear from you.


Copyright (c) 1997-99, Gopalan Suresh Raj - All rights reserved. Terms of use.

All products and companies mentioned at this site,are trademarks of their respective owners.