CORBA & Java IDL
Peter Komisar
©    Conestoga College
      latest        v.  5.6    /   2010


Introduction to CORBA


It must be admitted, CORBA is the first thing we have
looked at that is bigger than Java, as if that were possible!
Java is just one of many languages that is able to use the
CORBA architecture. The great thing about CORBA is that
it allows many different languages to communicate with
each other.


The Problem of Integrating Heterogeneous Platforms

'The Java Developer's Handbook' by Heller & Robert's
describes a scenario that
many major corporations found
themselves in. By the mid-seventies,
many companies
had mainframes they used for various business support
chores
, including tracking inventory, doing trend analysis
and generating artwork for branding and advertisement.

In the early 80s relatively cheap PCs became available
and started to
proliferate in the companies various
departments. The engineering department
might have
acquired Unix-based workstations while the art department
might have
collected Apple computers. The business divisions
might have added IBM PCs
.

Company Heterogeneous Computers in the Mid-Seventies

When networking became a possibility, the idea of the
company
connecting all the different computer types
became very alluring. What the firms found out though
was that the many different machines
had not been
conceived or designed with inter-communication in mind.
To make many machines, working on different operating
systems and hardware and programmed in different types
of programming languages communicate
turned out to be
a difficult and expensive proposition.

 

The Object Management Group, OMG

The Object Management Group was formed to address
this issue.
Initially OMG was just a group of engineers,
but with time, OMG grew
to a large consortium with over
800 member companies. The Object Management
Group
came up with CORBA, the Common Object Request
Broker Architecture
that allowed different types of
computer platforms to intercommunicate.

Now OMG is also the custodian of UML, the Unified
Modeling Language, which is a related topic in that UML
provides a
language neutral, object-oriented visual
modeling language. OMG also overlooks
the ODMG,
which stands for Object Data Standard. ODMG
provides an object-
oriented way to manage databases. 

Following is a link to the OMG FAQ page introducing
CORBA.

OMG's FAQ Introducing CORBA


http://www.omg.org/gettingstarted/corbafaq.htm

 

What is CORBA?    // the trick is IDL 

CORBA is described as a distributed objects framework
became it is an object-oriented distributed computing
architecture. CORBA allows programs that are written
in different computer languages running on different
operating systems and hardware to communicate with
each other using a language neutral interface language
called IDL or Interface Definition Language.

// CORBA allows a heterogeneous set of computers communicate
// via IDL,Interface Definition Language which is language neutral.

CORBA uses ORBs or Object Request Brokers to broker
method invocations between objects running on different
machines. The secret to making the system work is that
the individual ORBs take care of translating the platform
specific aspects of requests and responses into the
language neutral layer that CORBA utilizes.

// ORBs or Object Request Brokers 'broker' method
// invocations
between objects running on different machines

The OMG only maintains the CORBA specification. It
leaves commercial implementation of the standard to
ORB vendors. You can see a list of companies that
have developed CORBA solutions at www. corba.org .
More famous producer's are Borland who make Visibroker
and IONA that make Orbix. As well, IBMs 'WebSphere',
comes with an ORB implementation.

More Recently the Open Source community and projects
like JBoss are providing support for CORBA Orbs.


Why Use CORBA?  // legacy migration 

One of the major benefits of CORBA beyond allowing
different platforms to communicate is it provides a
vehicle for the migration of legacy
code and data, worth
billions of dollars, into a network-centric model.
Legacy
code can continue to run along side newer types of
information systems.


CORBA Architecture

OMA , Object Management Architecture


The OMG calls the framework of applications that work
together to form a
CORBA system the OMA or Object
Management Architecture. There are
a core set of these
elements that every CORBA implementation will include.

// framework of applications --> Object Management Architecture

Each station, both client and server, will have an ORB
or Object Request Broker brokering CORBA messages.

A CORBA
system will have a COS or Common Object
Service. (The COS is also called
CORBAServices.)

Every CORBA implementation is based on the use of
IDL or Interface Definition Language. Each CORBA
implementation
supplies an IDL compiler that translates
interfaces written in IDL into the native
language being
used by a client or server to write their distributed
applications.


Core Aspects of a CORBA Implementation

Optional Aspect


The final aspect that is described as part of the system is
the CORBAFacilities,
also called Common Frameworks.
This aspect of the specification is variably supported and
may be viewed as an optional
.

The ORB      // The Object Request Broker

The ORB is the Object Request Broker. The ORB takes
messages from the client,
translates them into CORBA's
language neutral protocol, and transmits the message
to
the server's ORB.
The ORB on the server translates the
language-neutral message back into
it's native language,
processes the message and returns a response back
through the system.

Practically speaking the messages are method calls, similar
to Java's RMI where arguments are passed and
return values
are received. The ORB  is the 'go-between' taking care of
translating native code into, and out of, the language
neutral
forms used by the ORBs.

The ORB is Sometimes Called an 'Object Bus'

The ORB is sometimes also described as an 'object bus'
as it provides a pathway
for objects to be made available
across different address spaces. Each computer that
is a
node on CORBA network will be represented to the system
by an ORB whether client
or server. Clients and servers
communicate over the CORBA system via their ORBs.

In addition to allowing computers to communicate remotely
the CORBA ORB adds the unique service
of 'brokering'
requests and responses between totally different machines
using
different languages, hardware and operating systems.

A hypothetical analogy here might be a phone service
where people speaking different languages have their
conversations
translated so they can understand each
other.

// CORBA limit it's translations to arguments & return values

CORBA is much more limited than this analogy implies.
CORBA limits it's heterogeneous platform communication
to the transmission of
method parameters and return values.

French English Language Translation Analogy

For instance, one machine might say 'Donnez moi deux
pommes'. The other machine hears 'Give me two apples'
and replies '2 apples sent'.
The original machine hears
'Deux pommes envoyees'.

Each ORB used is familiar with the native language of
the machine  it is being hosted on
so takes care of
translating in and out of language-neutral 'Corbese'  to
the language that
is being used on the machine. Beyond
the basic responsibilities of handling the network
connections and the message parameters
the ORB is
also responsible for concurrency or synchronizing
simultaneous requests that
might come from multiple
clients.

 
// the ORB also provides multiple request synchronization

 
CORBA Client Server Exchange Pattern

CLIENT  <->  ORB  <- object bus->  ORB  <->  SERVER
 

COS    // Common Object Services

The Common Object Services define a number of services
that CORBA specifies including features needed by CORBA
to operate as a single secure distributed system. Services
include mechanisms to locate services, respond to events,
maintain security and provide transactional processing against
databases. Other services include time services, processes
to allow data replication, messaging services and ways to
store stateful objects in long term memory. The services
that are deemed essential to CORBA's operation will come
with the vendor's ORB implementation.

 Four Main COS Services


Other Notable COS Services


In addition to the services listed above there are also
Licensing, Data Interchange,
Change Management, 
Messaging and Start-up Services.

IIOP // Internet Inter-ORB Protocol

The IIOP is an abbreviation of  Internet Inter-ORB Protocol.
IIOP is as TCP/IP
implementation of General Inter-ORB
Protocol (GIOP) The GIOP specification defines how ORBs
communicate with each other over networks. The GIOP
specification describes how messages are to be sent, how
bytes are ordered and how parameters are handled during
remote method calls.

// GIOP specifies how messages are sent, how bytes
// are ordered and how parameters are handled

CORBA 2.0 Compliance Has Strengthened CORBAs Position

IIOP compatibility is required for CORBA 2.0 compliance.
Heller & Robert's in the 'Java Developer's Handbook' point
out that the standardization that CORBA
2 has brought to
ORBs has greatly strengthened CORBA's position in the
world
of network computing. This is because CORBA 2.0
compliant, ORBs provided
by different vendors are now by
definition inter operable.

// CORBA 2 strengthens CORBA's footing as it specifies
// that different vendor's ORBs must be inter operable

 
 Object Adapters   
// server-side runtime environment, like a servlet engine

An Object Adapter is a server side application that supplies
a runtime environment in which CORBA objects can be
managed. The Object Adapter serves in a way similar
to
how AppletContext provides a runtime environment for
applets or a Web server's servlet
engine supplies an runtime
environment for servlets to run in.

The first Object Adapter that CORBA 2.0 specified was
called the BOA or Basic Object Adapter. It is a basic
adapter
that needs to be supplied with every ORB implementation.
With CORBA
2.2 the POA or Portable Object Adapter was
introduced.


The BOA or Basic Object Adapter    // from BOA to POA

Early CORBA specified a BOA or Basic Object Adapter.
The BOA instantiated CORBA objects and returned
references to them that could be used by clients. The
BOA also invoked object methods on behalf of clients.
Other tasks included maintaining security and activating
and deactivate CORBA objects to and from a persistent
state.

However, the BOA specification was vague and led to
much variation in how different vendors implemented
the BOA's tasks. ORBs were created that to different
degrees took on the Object Adapters tasks for themselves.

// BOA specification was vague and standarization
// was being lost to proprietary implementations


The POA or Portable Object Adapter
// carefully defined

To overcome these problems, the BOA was deprecated
in favor of a carefully defined POA or Portable Object
Adapter. The POA standardized the relation between
the objects, the adapter and the ORB implementation.
The POA was designed to be portable so that a CORBA
object collection could be used with different ORB
products.

The POA was again charged with providing persistence
and transparent activation support for CORBA remote
objects. The POA was given additonal duties in managing
CORBA such as lifecycle management. 


Description of a Portable Object Adapter in a CORBA System

     Client            Set of Corba Objects
      |                      |
    Stub                   
POA
      |                      |
Client ORB  <-network->  Server ORB

 

In the early years, say between 1997 and 2002, the BOA
had been implemented by many different vendors, while
the POA was still in
the process of being adopted. Now
however the POA is alive and well as of JDK1.4 and later
so we can expect to hear less and less of BOA and more
and more of POA!

CORBA 3 & Where CORBA is going

" Embedded systems developers have embraced the Common Object Request Broker Architecture (CORBA) standard as a means for integrating with enterprise systems and supporting network management. Despite
the overall popularity of CORBA, it has not been widely used for developing time-critical components of distributed real-time applications. This is because CORBA did not address real-time requirements, leaving it as an exercise to the user or CORBA vendor.

In order to extend the benefits of CORBA to real-time systems, the Real-Time CORBA specification was adopted in 1999. This standard tackles the key issue of end-to-end predictability across a CORBA system, and provides its solution in terms of priority control, synchronization, protocol selection and other forms of resource control. "

                                                              -from CORBA web site

http://www.omg.org/news/whitepapers/index.htm#CORBA/IIOP



CORBA Mechanics

Following is a simplification of a detailed description provided
originally by David Chizmadia, in a "Quick Tour of the CORBA
Security Service
", found at the OMG website. 
 

A Description CORBA Interaction

The stub routine makes a native call on the ORB. The
ORB transforms the native call into a GIOP Request
which contains a CDR or Common Data Representation.
The CDR can represent all the IDL types in seven basic
formats that can cover every possible interaction. The
GIOP also carries an IOR, or Interoperable Object
Reference that allows the CORBA object that represents
a service to publish where client ORBs can find it.

// native call to GIOP Request containing IDL representations

The GIOP is then passed to the transport layer. The
message that is sent over IIOP or Internet Inter-ORB
Protocol for transmission over the Internet is called the
transport message.

At the server, in addition to a basic reversal of the process
described above, parameters have to be extracted and
applied to a call on a method defined by a CORBA object
stored on the Server.

This management of the CORBA  object can be thought of
actions of a Skeleton, Object Adapter or a combination of
both. The call on the Server objects will be native so the return
values will need to be retranslated into the neutral dialect of
CORBA and sent back to the client.

Table with Key Points From Detailed Description of the CORBA Transaction
 
  THE CLIENT       THE   OBJECT IMPLEMENTATION
 native call on stub                   ( native call  layer )  makes calls on object
 calls the ORB where             ( stub skeleton layer )
 Skeleton takes
native
call info
 GIOP processes 
 native to neutral 
                ( Conversion
layer )  GIOP processes
 neutral to native 
 GIOP request.               ( Generic Inter-  Orb Protocol)  GIOP request
 TCP packaged    message(request)        < -- ( Internet Inter-  Orb Protocol ) -->  TCP packaged
 message(request)


RMI-IIOP

CORBA is similar in function to RMI but more complicated
having added the extra IDL layer to translate the differences
between languages, operating systems, and hardware. 

Because of the similarities, little modification of the CORBA
system is required to to support RMI over IIOP and there is
strong support for bridging the use of RMI with CORBA in
an API called RMI-IIOP.


The Name Service & the IDL Compilers


CORBA Name Service

Like RMI, CORBA uses a name service to locate remote
objects. Resolving and binding of remote objects is managed
in a separate process. The Java Development Kit supplies
a transient name service called 'tnameserv'. It does not
persist objects it registers. Name services that come with
commercial CORBA products will provide persistent name
services.

CORBA code is more complicated and has more steps
then RMI as the naming service has to first be resolved
from among the other COS services that are available.
This will be apparent when we look at code examples.
The following example shows the CORBA naming service
being started to run on port 1050.

Starting Java's Transient CORBA Name Service

C:\> tnameserv   -ORBInitialPort 1050      // DOS
 


IDL, Interface Definition Language

The slight of hand that enables different languages to cross
communicate requires the programmer to first write to the
language neutral, Interface Definition Language (IDL). IDL or
Interface Definition Language 
is a language-neutral grammer.

IDL is said to be compiled but it is really does a translation
via some language specific tool,
into a native language's
interfaces. IDL compilers are available for C, C++, Java,

SmallTalk, COBOL and Ada and other languages. The
CORBA interface definitions (ORB, COS &
Common
Frameworks) are all written in IDL language constructs.


'idlj' Replaces 'idltojava'

In Java, code for a CORBA application is first descibed in
the interfaces of IDL. On older Java systems, (JDK 1.2 and
earlier) the IDL script is then run through the 'idl to java' compiler,
called 'idltojava'.

On newer JDK releases the 'idlj' compiler is used to
generate the Java classes and interfaces which have
the CORBA architectural hooks built into them. The
Java programmer then fills in the implementation details
in the framework that the 'idlj' compiler has provided.


The idlj compiler

The idlj compiler has been available since Java's JDK1.3.x.
The compiler comes with the distribution so does not have to
be downloaded. The following page is still active at the Sun
site (as of 2010 ) and describes the transistion between the
two systems.

http://java.sun.com/j2se/1.3/docs/guide/idl/jidlChanges.html



IDL To Java Mapping


The Interface Definition Language resembles more than
any other language, C.
It adopts C syntax for legacy C
types such as structures unions and enumerated
types.
IDL does not support operation overloading or overriding
but does support single and multiple inheritence.It borrows
the C++ colon syntax to dictate support
for inheritance.
IDL has a number of types that are used to map support
for Java's
primitive types, arrays, class objects, methods
and exceptions.


The IDL file
// save IDL files to the .idl extension

The IDL code is written and saved to a file with an .idl
extension. This file will translate into a structure in the
native language for which the translator was written, in
our case, Java. The IDL file is passed to idlj (or idltojava)
compiler which creates the corresponding CORBA files
in the native language for which the compiler has been
designed.


Primitives and String type

IDLs float and double map to Java's float and double.
IDL's long and unsigned
long map to Java's int type.
IDL long long and unsigned long long map to Java's
long.
The IDL short and unsigned short map to the Java type
by the same name.
IDL char and wchar both map to
Java's char type. The boolean type is the same
in both
languages.

IDL uses the classic 'octet' keyword for one byte of data
that
maps to Java's byte type. IDL's string and wstring
map to the Java object type
String. The IDL boolean
constants TRUE and FALSE are mapped to
Java's 
boolean literals, 'true' and 'false'.


Table of IDL to Java Mappings for Primitive Types

 
 IDL   JAVA 
 float   float
 double   double
 long, unsigned long   int
 long long, unsigned long long   long
 short, unsigned short   short
 char, wchar   char
 boolean   boolean
 octet   byte
 string, wstring   java.lang.String

 

Mapping to Java's package, class, interface, method & constant

The following table shows IDL structural types, operations,
exceptions and attributes map to Java types. The IDL
keyword 'module' corresponds to the Java package. The
C type, enum, struct and union all map to Java's class. 

The IDL interface, aside from mapping to a Java interface,
also results in the creation of the set of CORBA support
classes generated by the IDL to Java compilers. The
constant IDL type translates to the Java's equivalent of a
constant, a type with the modifiers public static and final
prefixed. The IDL exception maps to a Java class.

The IDL 'readonly' and 'readwrite' attributes map to Java
methods, either just an accessor method or both 'get' and
'set' methods in the case of a 'readwrite' attribute.

Table showing other IDL to Java type Mappings
 
 IDL type
 Java Type
 module   package 
 enum, struct, union   class
 interface   interface, helper, holder,
 implementation, stub 
 constant   public static final
 exception   class 
 readonly attribute  method for accessing
 value of attribute 
 readwrite attribute  creates accessor and
 mutator methods
 operation
 method  // 'operation' like
 'method' is not a key word



Note from Mapping IDL to Java

"When a CORBA operation takes a type that corresponds to a Java object
type  it is
illegal to pass a Java null as the parameter value. Instead, pass
an empty version of
the designated object type (for example, an empty String
or an empty array). A Java
null can be passed as a parameter only when the
type of the parameter is a CORBA
object reference, in which case the null is
interpreted as a nil CORBA object reference."

                                       -  jdk1.2.2/docs/guide/idl/mapping/jidlMapping.html


IDL Components

The IDL module    // maps to Java package

The IDL module construct defines the enclosing scope of
one or more IDL interfaces and may contain other nested
module constructs. The module maps to a Java package.


Example

   module Z_Company{
        module Department{
            interface Files{
            };
          };
        };

Saving this code to a file called Z_Company and passing
it as an argument
to either the idltojava or idlj compiler will
generate a package in a package, Z_Company.Department
in which is the 
Java code for the Files interface and associated
CORBA Java files. The contents
varies depending on the
translator. The following shows the output of the
classic
'idltojava' translater. It is similar to the output of the newer
RMI compiler. Note though that Java source files have been
created by the idl compilers.


Example

IDL interface maps to several Java interfaces / files.

1) A Java interface class with same name as the IDL interface identifier
2) An implementation base class containing skeleton code for the server
3) A stub class for the client
4) A helper class for narrowing references returned from the Naming Service
5) A holder class to contain an IDL type reference


Example

1) Book.java
2) BookImplBase.java
3) BookStub.java
4) BookHelper.java
5) BookHolder.java


The idlj Compiler Options

The new idlj compiler is used a little differently. It separates
the classes that
will be needed by the Client from those that
are needed by the Server. When
used to generate CORBA
client classes the -fclient option
is used to generate
the same
set of classes as the idltojava compiler would create except,
an 'Operations' class is added
and the 'ImplBase' or
implementation base class is omitted.

When the idlj compiler is used to generate server side CORBA
classes the ImplBase class
is generated along with an Operations
class and the services interface.

//  Using idlj with -fclient generates an XXXOperations class and not an
// ImplBase class. On the server side, an ImplBase class is generated
// along with an Operations class and the services interface

idlj Compiler Generation Example  // client

1) Book.java
2) BookOperations.java
3) _BookStub.java
4) BookHelper.java
5) BookHolder.java

idlj Compiler Generation Example  // server

1) Book.java
2) BookOperations.java
3) _BookStub.java
4) BookHelper.java
5) BookHolder.java
6) FilesPOA.java


The IDL attribute  // variables with assc. methods

IDL uses the 'attribute' keyword to mark CORBA variable
types. These attibutes are automatically translated into
methods by the IDL to Java compilers. If the attribute
is marked 'readonly' then only an accessor method is
generated. If the attribute is marked 'readwrite' then
both an accessor and mutator method is generated.

In the following example the attribute is not marked
'readonly' or 'readwrite' and so will default to readwrite
and generate both methods. This is the output using
the idlj compiler. 


IDL Input 
// save as Price.idl

interface Price{
                    attribute float price;
                    };

// supply as argument to idlj

> idlj -fclient Price.idl


Java Operations Interface Created
// with other classes
  


/* CORBA style comments omitted */
public interface PriceOperations
   {
   float price ( );
   void price (float newPrice);
   } // interface PriceOperations

The get and set methods corresponding to the
price attribute are by default created.

IDL Operations

Operations compile to Java methods. There isn't an
operation keyword. All that needs to be done is to supply
the signature of the method you want to include. There
are some rules as follows. The key difference between
Java methods and IDL methods is the inclusion of the
'in', 'out', or 'inout' keywords in the parameter area.

Rules Governing IDL Operations

Operations: 

1) must have a return type
2) may have zero or more arguments
3) in parameters map directly to Java arguments
4) out and inout parameters map to the nameHolder class.

The reason 'out' and 'inout' parameters map to a holder
class is that J
ava doesn't support these types directly.
The same behaviour can be emulated by a Java object
type being passed into a method as an argument and
then the same object being returned after modifications
are made. This is what the holder class does, act as a
wrapper for these special non-Java types.

IDL Exception

IDL allow the creation of exceptions that generate the
type of exception one expects from Java. There are a
couple of things to note. First, exceptions must be declared
before they are called. Also exceptions are not mapped
directly to Java Exceptions. Instead they are created as
subclasses of org.omg.CORBA.UserException.


IDL Exception Example

exception EastWindException{
               string reason;
               };


The IDL 'raises' Keyword

IDL operations can be declared as throwing exceptions
with the IDL keyword 'raises'.

IDL Input

 module C_Company{
         exception EastWindException{
           string reason;
           };

   interface Winds{
       void prevailing_wind(in  boolean WEST)
               raises (EastWindException);
              };
        };

idlj Output

public interface WindsOperations
{
  void prevailing_wind (boolean WEST) throws C_Company.EastWindException;
} // interface WindsOperations
 

IDL struct

As mentioned earlier IDL uses some C data types. For
instance in the following example the struct is used to
create a collection of data for a book.  A single Java
class with public data members.

Example   

struct Book {
  string title;
  string author;
  string isbn_number;
  float price;
  };

Among the classes created, the one that represents the
'struct' defined above is marked 'public' and  'final'. Book
with a no-args constructor and a constructor that will
accept initialization for all the variables in the order they
are listed in the structure.


IDLJ Output

public final class Book implements org.omg.CORBA.portable.IDLEntity
{
  public String title = null;
  public String author = null;
  public String isbn_number = null;
  public float price = (float)0;

  public Book ( )
  {
  } // ctor

  public Book (String _title, String _author, String _isbn_number, float _price)
  {

    title = _title;
    author = _author;
    isbn_number = _isbn_number;
    price = _price;
    } // ctor
    } // class Book 


IDL typedef

The typedef construct allows defining new IDL types from
existing ones. The IDL compiler will set the type back to
actual type before compiling. A helper class is created to
allow a Java type to be represented by a different name.

Example            

typedef    string         Name;
typedef    long           Salary;
typedef    sequence  <long> ID;


The helper class is stored in a FunctionsPackage and has
a Java file named after the name adopted to represent the
type definition. The class stands in for the typedef, reading
and writing to stream the required definitions as needed.


IDL sequence

The IDL sequence represents a single dimension array.
The sequence may be bounded where it's maximum value
is set or unbounded. In the following example ten IDL longs
will create a single dimension int array in Java with ten cells.
As with other type definitions a helper class is generated
and also a holder class to hold the values of the array in
the CORBA system.

Example   

typedef sequence < long, 10 > Orders;


The holder class generated for this example is called
OrdersHelper.java and contains a regular Java style int
array. It also contains a constructor that receives an
array and a read and write methods to send and receive
values to and from it.

// Creates a holder class with an array and associated
// accessor and mutator methods


IDL Arrays

IDL also supplies an array construct to creates a single-
dimension array which appears more like a Java style
array.

Example         

const long length = 20;
typedef string name[length];
 

IDL enum

The IDL enum type creates an enumerated list. The list
is emulated by three classes, a Java with same name
and a helper and holder class.

Example     

module F_Company{
      enum  Teams { Yankees, Expos, BlueJays };
      };

There are some other IDL types like the Union that behaves
like the struct which maps to a Java class. Also of note
are constants which map to public, static final variable
in the Java code.

IDL Constant Declaration

We will end this quick tour of IDL with
an example of an IDL constant declaration.

Example   

const float baseValue = 1000.00;

idlj Output  

public static final baseValue = 1000.00;



Detailed Summary of the Steps in Creating a CORBA System

At this moment we are in the year 2010. The idltojava
interpreter is not even offered in Java 6. I leave the
references to the old way of compiling a CORBA system
just for historical record.

We have looked at the parts of the CORBA architecture
now it is time to go through the steps of creating a CORBA
client server application. The recipe for creating CORBA
applications is similar to RMI but with the added step of
creating the IDL interface definitions which need then be
mapped to the Java language.

The steps in brief are first to create the IDL file, compile
with an IDL to Java compiler. If the newer idlj compiler is
used the compiler will be used twice, once for the client
with the appropriate flags and then for the server with
the -fserver flag.

The generated class files are then used in creating an
implementation of the CORBA services. These may be
compiled first.  A client and server will have to be built
and then all three of these will also need to be compiled.
The system is then ready to be tested.

The naming service is started first followed by the server
and then the client. The steps to take are listed below.
The list is adapted from one in the Developer's Handbook
by Heller & Roberts. It has been modified to provide to the
new idlj compiler.

Note: the idltojava command
// You might want to stick with the new trail using idlj

Summary of the Steps in Creating a Classic CORBA
System 
// See link below for new 10 Steps with a POA

 1.  Create the IDL file
 2.     a) Compile using idlj for each of the client and the server
         b) OR  if you have an old JDK compile the IDL file using idltojava    
 3.  Compile the generated .java classes using javac
 4.  Implement the methods
 5.  Create the implementation server
 6.  Create the client application
 7.  Compile the implementation, server and client code
 8.  Start the Naming Service, tnameserv
 9.  Start the server
10. Start the client

1. Create the IDL file

We have spent sometime looking at IDL so this part of it
should be straight ahead.
First the interface for the services
and structure of the remote Corba object must
be defined.
We are going to build a voting system. In our example we
will illustrate the use of both, the
classic idltojava compiler
and the newer idlj
compiler.

Following is a declaration that will result in a package
that contains
an interface called votes being created.
The interface defines two methods that
return how many
votes were cast for the Liberals or the Tories.


IDL Example

module vote_poll{
    interface votes{
         long get_Liberal( );
         long get_Tory( );
         };
      }; 


  2. a ) Compile the IDL using  idlj

// Things have changed again with CORBA! To continue with
// this 'recipe' we need to specify the -oldImplBase
flag when '
// idljing' the server. This creates the _votesImplBase class we
// extend to create an implementation base.

If using the idlj compiler which comes with the new JDKs
a different option is used to generate the classes for the
client then is used for the server. The following line is an
example of the client stubs being generated.

Client Example    

idlj -fclient vote_poll.idl

// this command generates  votesHolder.java, votesHelper.java,
//  _votesStub.java votes.java and votesOperations.java


Notice we are using the -oldImplBase flag to generate
an _votesimplBase.java class.


Server  Example    

idlj -fserver -oldImplBase vote_poll.idl

// this command generates votes.java and votesOperations.java
// and _votesimplBase.java

When using the idlj compiler the primary interface no
longer carries the methods
that are defined in the IDL
file. Instead, an operations class is generated and
housed
in a subdirectory that contains these methods.
This operations interface is
shared by both stubs and
skeletons. The operations interface is not used directly
by
the developer so we don't have to worry about it.


OLD OPTION

 2. b) Compile the IDL using idltojava  // for older JDKs

The above IDL module needs to be saved as a text file with
an .idl extension. If it was compiled using the classic idltojava
compiler the command would take the following form. The
idltojava is written in native C++. That is why the -fno-cpp

flag is used. These are preprocessor directives where
-fno-cpp option turns off
C/C++ preproccessing. The newer
idlj is written all in Java and so doesn't require
these options.

Example    idltojava-fno-cpp vote_poll.idl

 // leaving out the no pre-proccessor flag results in an error

A new directory called vote_poll is created in the current
directory
which contains the following Java files, votes.java,
_votesStub.java,
_votesImplBase.java, votesHolder.java
and votesHelper.java.

 
 
 votesHolder.java   - holds parameter types not supported by Java
 votesHelper.java   - provides other kinds of help accessing types
 _votesStub.java   - provides a proxy for the client to make remote calls 
  votes.java   - provides the interface implemented by the remote object
 _votesImplBase.java   - extended to supply the remote object implementation 



3. Compile the generated java files

Once the files are generated they can be compiled. Notice
they are in a package that corresponds to a directory so
they are compiled from.

Example     javac vote_poll \*.java
 

4. Create the implementation class

The implementation class is created by extending the
_name
ImplBase and
providing definitions for the methods
defined in the idl file. By extending the
implementation
class, all the hooks neccessary for the object to cooperated

with the CORBA system are automatically added. All this
is cleanly hidden
away and the developer can concentrate
on supplying definitions for the
method signatures.


Implementation Example

package vote_poll;

public class votesImpl extends _votesImplBase{
   static int l = 0;
   static int t = 0;
   public votesImpl( ){    // recommended no-arg, empty constructor
   }
     /* method implementations */
   public int get_Liberal( ){
      l ++ ;
      return l ;
     }
    public int get_Tory( ){
       t ++ ;
       return t;
      }
}

5. Writing the Server

The server class starts by calling init( ) on the ORB class
to return an ORB object.
Notice OBBs are not instantiated
but rather returned from an init( ) method. The
init( ) method
has three overloaded variations all which return an ORB
object. The
no-args form is used internally by the CORBA
system. The second form takes an
applet instance and an
Properties object. This form of the method is used with
applets.
The third that takes a String array and a Properties
object is used with stand-alone
applications.

Notice the third form designed for standalone applications
has a string
array that corresponds to the main( ) method
array that receives parameters at the
command line. The
array in the init( ) method allows passing in parameters
directly
from the command line. The properties object can
be used to pass in other
parameters.

Variations in Signatures of ORB's init( ) Method


After the ORB is obtained the implementation object is
instantiated and it's
reference is passed to the connect( )
method of the orb. This object needs
to be bound or
registered with the naming service. First the Naming
Service
is resolved from among the various CORBA
COS services. This reference is
then narrowed to a
NamingContext object.

A name, in our example Votes' is encapsulated as a
NameComponent object and then in turn an array of
NameComponents
. This is the form that is needed to
bind the name to the remote service
object. This is done
using the rebind( ) method of the NamingContext object.

The object then uses Java's Object class wait( ) method
to wait to be called
into service.
 

Corba Server Code Example

import vote_poll.*;
import org.omg.CosNaming.* ;
import org.omg.CosNaming.NamingContextPackage.* ;
import org.omg.CORBA.* ;

public class vote_poll_server {
public static void main( String args[] )
{
  try{
        ORB orb = ORB.init(args,null);
        votesImpl vI = new votesImpl( );
         orb.connect(vI);
     // binding the object with the  name service
     org.omg.CORBA.Object corba_object = orb.resolve_initial_references("NameService");
     NamingContext naming_context = NamingContextHelper.narrow(corba_object);
     NameComponent namecomponent = new NameComponent("Vote", "");
     NameComponent path[ ] = { namecomponent };
     naming_context.rebind(path, vI);

      // Synch on Object object and wait for client invocations
     java.lang.Object sync = new java.lang.Object( );
     synchronized (sync) {
     sync.wait( );
     }
     }
     catch(Exception e){
       System.err.println("Error " + e);
       }
   }
 }

6. Writing the Client

The client locates a reference to the CORBA object using
the Naming Service. The Naming Service location can be
specified at the command line as an option or as a property
passed to the ORB.  The following examples show both
these options.

Example Starting Client Specifying Host and Port Number 

java Client -ORBInitialHost  234.23.4.5 -ORBInitialPort 1050

// supplying the name service IP address and port from the command line

Example Passing Host and Port Information via Properties Object

Properties props=new Properties( );
props.put("org.omg.CORBA.ORBInitialHost", "234.23.4.5");
props.put("org.omg.CORBA.ORBInitialPort", "1050");
Orb orb=ORB.init(args, props);

// supplying the name service IP address and port as a Property object


As described earlier for the server code, in CORBA the
Naming Service has to first be filtered from other COS
services. This is done using the resolve_initial_references( )
method for the particular service needed, in this case the
naming service.

The naming service then supplies an initial context which
is obtained by first using the narrow( ) method of the
NamingContext's helper class. The narrow( ) method
returns an object of the NamingContext class. The
following two lines shows these steps.


Example Showing Service and NamingContext Narrowed

org.omg.CORBA.Object  cor_obj = orb.resolve_initial_references("NameService");
NamingContext naming_context = NamingContextHelper.narrow(cor_obj);

Once the naming context has been returned, the object
reference can be obtained for the CORBA remote service.
First the service name is wrapped in a NameComponent
object. The NameComponent constructor takes a String
that represents the name of the CORBA object and a
second string that can be empty that supplies a description.

The resolve( ) method of the naming context object takes
a NameComponent array.  The following lines shows the
"Vote" name being packaged in the form needed by the
resolve( ) method which takes the NameComponent array
reference as an argument. Notice it had to undergo another
narrrowing via the narrow( ) method of the votesHelper class.

Example

NameComponent nc = new NameComponent( "Vote", "");
NameComponent path[] = { nc };
votes vI = votesHelper.narrow(naming_context.resolve(path));

Finally the returned object reference can be used via the
dot operator like any other object to call the objects methods.
The following Client example shows all these stages.
 

Corba Client Example

import vote_poll.* ;
import org.omg.CosNaming.* ;
import org.omg.CosNaming.NamingContextPackage.* ;
import org.omg.CORBA.* ;

public class vote_poll_client{
 public static void main( String args[] ){

  if (args.length!=1){
     System.out.println("Vote by specifying a party, Liberal or Tory. ");
     System.exit(1);
     }
     String party_vote=args[0];
  try{ // Use the ORB instance and Naming Service to obtain a remote reference

      ORB orb = ORB.init(args, null);
      org.omg.CORBA.Object  corba_object = orb.resolve_initial_references("NameService");
      NamingContext naming_context = NamingContextHelper.narrow(corba_object);
      NameComponent nc = new NameComponent( "Vote", "");
      NameComponent path[ ] = { nc };
      votes vI = votesHelper.narrow(naming_context.resolve(path));

     // use the reference to call remote CORBA methods
      if (party_vote.equals("Liberal"))
         System.out.println( "The vote is Liberal and the new tally is " + vI.get_Liberal());
      else
          if (party_vote.equals("Tory"))
            System.out.println( "The vote is Tory and the new tally is " + vI.get_Tory());
          else
            System.out.println("Your ballot has been discounted");
   }
   catch(Exception e)
   {
   System.out.println("ERROR : " + e);
   }
 }
}

7. Compile the Server and the Client  & Implementation class

In the case of the client and server they have been defined
as importing the vote_poll
directory. So these classes
should be compiled in the directory above vote_poll
directory.
On the other hand the votesImpl class is
declared as being part of the package vote_poll
so it
should go inside the vote_poll directory. The following
example shows the appropriate compiles. 

 
Command Line javac Compilations

>javac vote_poll_client.java
>javac vote_poll\votesImpl.java  // votesImpl is in the vote_poll package
>javac vote_poll_server.java
 

8. Run the Name Server

Because we are using the command line to supply
arguments we will use the default technique which
will start the CORBA system on port 900. To use
another port, we could use the Properties object
to supply alternate addressing. This way the command
line remains unencumbered to pass in arguments.

Enter tnameserv at the command line and press enter.
The service will default to port number 900. The following
examples shows how the initial port can be explicitely
specified.

C:\> tnameserv 

// naming service default port number is 900

When you start the tnameserv you will see a very long
number. That is the IOR
or Interoperable Object Reference
followed by the current port number. The IOR
describes
a service and where it's located.


9. Run the server

The following shows the server being started on the
default
port number 900.

>  java vote_poll_server
 

10. Run the client

>   java vote_poll_client  

If everything runs as expected the client will prompt the
user to enter Liberal or Tory at the command line and
will keep a tally of each type of vote.


CORBA Recipe Using the POAAdapter


CORBA is a moving target. The POAAdapter is now
part of the active scenario and a new heavier weight
naming service is included in latest JDK distributions.

Rather than make this note too long I include a link
to a page which shows a summary of the new formula
which makes use of CORBA's new pieces.

New CORBA 10 Step

 


Conclusion



That is the basics of creating a CORBA service. There
are few subjects we
are leaving out. For instance the
issue with dealing with out and inout parameters.
If you
need details of using out and inout parameters this
information can be
obtained in the documentation or at
the Sun site. IDL mapping information accompanies the
JDK distributions.

There is also an interesting API called DII or Dynamic
Invocation Interface that allows a client to access a

CORBA object even though it doesn't have a client
CORBA stub.

Finally the adoption of RMI for use with CORBA in the
RMI_IIOP is a significant
trend in that allows the developer
to return to writing RMI applications that run over the
CORBA system.

 


Note

No questions on CORBA on the final exam!


Exercise

Note any one of the assignments is optional. If you have
enough in you are finished your term work. However this
assignment is straight ahead and you may wish to do it
anyway for the hands on experience.

On the other hand, if you are missing an assignment you
should do this one as it is just of casing of running the
supplied code. There is a minor bonus point for running
the code and submitting in the case that all your assignments
are in.

In the following you may choose to use the new POA
formula or the older formula in which case additional
flags are now required.

1. Run the  Vote code and submit screen shot of the output.

Optional

2. Create a CORBA Client and Server Example that returns a
credit rating for an individual name passed in. If the name is not
in the list a message to indicate no credit rating is available
should be returned.