references:
1) 'Developer's Handbook' Heller-Roberts
,2) ' Introducing Java IDL' ,The Java Tutorial,
3) jdk1.2.2 at /docs/guide/idl/mapping/jidlMapping.html,
4)'A Quick Tour Of the CORBA
Security Service by David Chizmadia
5) ' Advanced Java' Clifford
J. Berg
The problem CORBA was Designed to To Solve
'The Java Developer's Handbook' by Heller &
Robert's describe a problem
scenario that many major companies found themselves
in. CORBA was invented
to provide a solution to this problem. The story
basically goes like this. By the mid
seventies many companies had mainframes they
used for various business support
chores such as creating graphics to generate
artwork used for branding and
advertisment. The mainframe would also be used
for doing trend analysis and
keeping track of inventory. At 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 would be adding IBM
PCs to the office. When networking became a possibility,
the idea of the company
connecting all the disparate computers into a
grand inter-communicating system
became very alluring. What the firms found though
was the many different machines
had not been conceived or designed with intercommunication
in mind. Making many
machines, with programs written in different
programming languages, resting on
different operating systems and hardware communicate
with each other turned out
to be a very difficult and expensive proposition.
The Object Management Group, OMG
This is the problem the Object Management Group
was formed to address.
Initially the OMG was just a group of engineers.
As time went on 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. Besides
CORBA, the OMG are also the official custodians
for other world standards.
They now oversee UML, the Unified Modeling Language,
which is platform and
language neutral, object-oriented visual modeling
language. They also overlook
the ODMG, which stands for Object Data Standard.
ODMG provides an object-
oriented way to manage databases.
What is CORBA?
CORBA is descibed 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 each other using a language neutral interface
language
called IDL or Interface Definition Language. CORBA uses a 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 of CORBA. 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.
Why Use CORBA?
So why go through all the trouble? One of the
key benefits of CORBA beyond
allowing heterogeneous platform communicate is
it allows the migration of legacy
code and data, worth billions of dollars, into
a network-centric model. This enables
the investment in legacy code to continue being
used along side newer more unified
information systems.
Corba and Java
Java integrates support for CORBA into it's standard development kit
distributions.
Some of it's components are light weight and intended primarily for
a reference for
development. For instance, Java's ORBs do not use persistence or permanent
storage to back up it's data. More robust commercial ORBs provide persistence
for CORBA objects. The Java Enterprise Edition (J2EE) was designed
to provide
network solutions written in Java. The applications that are used to
host Enterprise
JavaBeans are called Containers. These containers are often designed
to run over
the CORBA architecture.
CORBA Architecture
The OMG call 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.
First there is the ORB. Each station will have
an ORB or Object Request Broker.
The ORB handles communications between the client
and the CORBA system.
The ORB serves the same role for the server as
it does for the client. A CORBA
system will have a COS or Common Object
Service. The COS is also called
CORBAServices. Every CORBA system implementation
is also predicated on
the use of IDL or Interface Definition Language.
Each CORBA implementation
will supply 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.
The final aspect that is described as part of
the system is the CORBAFacilities.
CORBAFacilities is also called Common Frameworks.
This part of the system
is not widely supported to date CORBAFacilities
can be viewed as an optional
part of a CORBA implementation even though it
is part of the specification.
Table Summarizing the Principle Components
of a Corba System
ORB | An Object Request Broker implementation |
COS | A Common Object Services a.k.a CORBAServices |
IDL | The Interface Definition Language & compiler |
CORBAFacilities | a.k.a. Common Frameworks // 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 target ORB
that is representing the server which will respond
to the request message. The ORB on the
server translates the language-neutral message
back into the native language of the server
and the server provides a response to the request.
The response, in like fashion is returned
back into the CORBA system and is returned to
the client.
Practically speaking the messages are method calls,
passing arguments and receiving return
values. The ORB takes care of translating
this information into a language neutral form and
then transmitting the information over the wires
of the network.
The ORB is sometimes also describes as an object
bus because it provides a pathway for
objects to travel between different address spaces.
Each machine that represents a node
on CORBA network will be represented by an ORB
whether client or server. While a
client would be represented by it's ORB the server
on the other side of a network would
have it's own ORB object, acting as a receiver
that translates messages from clients into a
dialect it understands. If you can imagine a
phone system that allows people speaking in
different languages to make very simple quantitative
info exchanges ( i.e Donnez moi deux
pommes .... 2 apples sent ) you have the
basic notion of what the CORBA system does.
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. It is in the sense
that the ORB 'brokers' between different
languages, platforms, and hardware that it get's
it's name Object Request Broker. Beyond
the basic responsibilities of handling the network
connections and the message parameters
the ORB is also responsible for concurrency,
the synchronizing of simultaneous request that
might come from multiple clients.
Figure 1 The basic exchange between a client and server over the Corba System
CLIENT <->
ORB <- object
bus->
ORB <-> SERVER
COS // Common Object Services
The Common Object Services define a number of services that CORBA specifies.
They
include the different aspects that are important to any computer system.
They are unique
in that describe services that are uniquely designed to operate in
the distributed architecture
that is CORBA. These services provide the mechanisms for the distributed
application to
locate services, respond to events, maintain security and provide transactional
processing
against databases. Other services include time services, and ways to
store stateful objects
in long term memory.
Our first objective will be to get a basic system running and to this
end we will just be
using the Naming service that is provided with the java distribution.
The different CORBA
services are listed in the tables below.
Common Object Services
Common Object Services assist the ORB providing The15 services
are:
The principal four services
Naming Service | -provides a hierarchial naming directory for CORBA
objects
enabling clients to request a reference to an object by name |
Event Service | -allows an EventObject to be sent to receiver(s)
-objects can request 'to listen' to specific event channels. The service notifies listeners of an event on that channel. (events are stored until passed) |
Security Service | -provides method authentication, authorizes object
accesses and secures communications |
Transaction Service | -controls database access with transaction 'commit' & 'rollback' |
The remaining eleven
5) Persistent Object Service | 6) Concurrency Control Service |
7) Life Cycle Service | 8) Relationship Service |
9) Externalization Service | 10) Query Service |
11) Licencing Service | 12) Property Service |
13) Time Service | 14) Object Trader Service |
15) Object Collections Service | . |
IDL
IDL or Interface Definition Language is
a
language-neutral grammer. IDL is said to be
compiled but it is really translated via some
language specific tool, into a native language's
interfaces. IDL compilers are available for C,
C++, Java, SmallTalk, COBOL and Ada.
The CORBA interface definitions (ORB, COS &
Common Frameworks) are all written
in IDL language constructs.
IIOP // Internet Inter-ORB Protocol
The IIOP is short for
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. The GIOP specification describes how messages
are
to be sent, how bytes are ordered and how parameters are handled during
remote
method calls.
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 interoperable.
BOA and POA //
reference
"An Adapter converts the interface of a class into another interface clients expect" Design Patterns, E. Gamma et al. Corba supports the idea of an Object Adapter. Object
Adapters create server objects
|
CORBA Transactions
In simplest terms, the Server provides a remote interface and the client
calls it. The CORBA
client holds a reference for the remote corba object. This reference
has a stub method which
stands in for the method being called remotely. The stub connects to
the ORB which handles
connecting and forwarding the invocation to the server. The ORB in
the process converts the
native environment message into Corba's language neutral format.
On the server, the ORB restores the language neutral message to what
is native on the server
machine and calls the skeleton code to convert the remote invocation
into a call on the
implementation object. After the calls have been processed, the skeleton
takes care of return-
ing these values to the ORB. The ORB once again retranslates the return
values to language-
neutral, GIOP format. The IIOP layer packages the GIOP message into
a TCP compliant
package and sends it back to the client.
Corba Operation in More Detail
This is a quote from part of "A Quick Tour Of the CORBA Security Service" by David Chizmadia, OMG Security SIG Co-Chair. View this article at http://www.omg.org/news/corbasec.htm "Conceptually, the interface stub routine calls on the ORB to transform the language-specific operation call into a language, operating system, and hardware independent GIOP (Generic Inter-ORB Protocol) Request. The GIOP defines a Common Data Representation (CDR) for all of the basic IDL types and seven basic request formats that cover all of the kinds of interactions between the client and object implementation, as well as an Interoperable Object Reference (IOR) that allows the Object Implementation to publish information that allows clients' ORBs to find and forward requests to it. The GIOP Request is then passed to a network transport processing layer,"..." the Internet Inter-ORB Protocol (IIOP). The transport processing layer transforms the GIOP object location information into the transport- specific address (TCP host and port for IIOP) of the Object Implementation and creates a transport Message containing the GIOP Request. The client-side ORB sends the Message to the ORB on which the Object Implementation runs. The receiving ORB's transport processing layer extracts the GIOP Requestfrom the Message and forwards it to the GIOP processing layer, which transforms the Request into the specific language, operating system, and hardware dependent format required by the Object Implementation. The Object Implementation code is then invoked as an upcall from the interface skeleton routine generated by the IDL compiler. After the Object Implementation completes its processing, it returns control to the skeleton routine, which sends the result back to the client stub, which returns the result to the client program. " . |
A one-method distributed object shared between a CORBA client and server.
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) |
Corba is similar in function to RMI but with the extra IDL layer to
translate the
differences between languages, operating systems, and hardware. Because
of the
similarities, little modification of the CORBA system was required
to to support
RMI over IIOP.
What is missing in our discussion so far is any reference to the naming
service. The
registration and looking up of the remote corba object is an activity
separate from
the transaction being described in the models. The remote calls happen
after the
connection between client and object have been made. The way the naming
service
is used in Corba is more complicated than in RMI and will be evident
when we
look at the code examples. As with RMI, the naming service will need
to be started
running in it's own process. The following example shows the CORBA
naming
service being started.
Example tnameserv -ORBInitialPort 1050
IDL to Java Mapping
For details see in the jdk1.2.2
at /docs/guide/idl/mapping/jidlMapping.html
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).
Code is first descibed in the interfaces of IDL. This idl script is
then run through the
idltojava compiler which translates the script into 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 idltojava compiler
has provided.
IDL Constructs and Java equivalents
primitives
and String
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 |
package, class, interface, method &
constant
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 isn't an IDL keyword |
Note from Mapping IDL to Java
jdk1.2.2/docs/guide/idl/mapping/jidlMapping.html
Note: When a CORBA operation
takes a type that corresponds to a Java object type (a String,
for example), 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. |
Holder Classes
// from jdk1.2.2 /docs/guide/idl/mapping/jidlMapping.html
IDL supports out and inout parameter but Java only supports in parameters. Java works around this by using "holder" classes to wrap the in and inout values.These classes are available for all of the basic IDL datatypes in the org.omg.CORBA package and are generated for all named user defined types except those defined by typedefs. 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, e.g. IntHolder. Each holder class has a default constructor that sets the value field to the default value for the type as defined by the Java language (i.e. false for boolean, 0 for numeric and char types, etc.) The holder classes are in the org.omg.CORBA package.
Example of a Holder class from the CORBA package package org.omg.CORBA; final public class ShortHolder {
Example of how Holder classes are used in place of an inout parameter interface InOutInterface{
public interface InOutInterface{
|
An IDL file is a composition of
several elements which together create a naming scope.
IDL does not support operation overloading or overriding but does support
single and
multiple inheritence
The IDL module construct defines
the enclosing scope of one or more IDL interfaces
and may contain other nested module constructs.
// ' module' maps to java's 'package'
example
module The_Company{
module Inventory{
interface Records{
. . .
};
};
};
// the idltojava compiler would create the package, The_Company.Inventory
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
examples 1) Records.java
2) RecordsImplBase.java
3) RecordsStub.java
4) RecordsHelper.java
5) RecordsHolder.java
IDL attribute
the IDL keyword marking CORBA variable types
Attributes generate get/set (accessor/mutator) methods for the type declared
example attribute float
price;
// the IDL attribute creates the following java methods
float price( );
void price(float arg); //
if attribute is marked read only then only accessor is created
IDL Operations
Operations compile to Java methods. There isn't an operation keyword.
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.
Java doesn't support
types that can be mapped comparably to out or
inout.
The
holder class serves
to mediate the differences.
IDL raises
IDL operations can be declared throwing exceptions with the IDL keyword
raises
example interface
Winds{
void prevailing_wind(in
boolean WEST){
raises (EastWindException);
};
};
IDL exception
Exceptions 1) must be declared before they are invoked
2) IDL exceptions don't map directly to Java Exceptions API rather they
map to
java classes that are extensions of org.omg.CORBA.UserException
class
example exception
StockException{
string reason;
};
interface
account{
void orderBooks( in Booklist books)
raises (StockException);
};
IDL struct
A container class used to pass a collection of data as a single object.
Maps to a Java class with public data members.
example struct
Book {
string title;
string author;
string isbn_number;
float price;
};
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.
example
typedef string
Name;
typedef long
Salary;
typedef sequence <long> ID;
IDL sequence
A single dimension array, bounded (where the maximum value is set)
or unbounded.
example typedef sequence < long, 10 > Orders;
An example of a bounded sequence of 10 IDL long numbers of type Orders
Exceeding bounds throws a MARSHAL
systems exception
Every sequence created has it's own Java helper and holder class
IDL Arrays
The IDL array construct creates a single-dimension array similar to
sequences
const
long length = 20;
typedef
string name[length];
IDL enum
IDL's enum creates an enumerated list which maps to a java final
class with the same name
example
enum Teams { Yankees, Expos, BlueJays };
Getting the idltojava compiler
Once you have written your code in IDL it needs
to be compiled through the idltojava compiler.
The jdk1.2 idltojava compiler is found at the
following site. //
use for the practical example below
http://developer.java.sun.com/developer/earlyAccess/jdk12/idltojava.html
The newer Version 1.3 of the Java 2 SDK, Standard Edition, includes
a new version of Java
IDL. The new IDL-to-Java compiler, idlj, is included with the download
of J2SE v.1.3. It has
a number of changes outlined at the following site.
http://java.sun.com/j2se/1.3/docs/guide/idl/jidlChanges.html
While spending time investigating IDL one should
be aware that since the RMI-IIOP
specification has largely been ironed out, writing
and compiling IDL can avoided! You
now have the option to write to Corba directly
over RMI. Essentially it comes down to
writing to RMI as usual with a few more restrictions.
See RMI_IIOP
IDL Development Steps
Heller-Robert's 10 steps to creating a CORBA
Service
including examples from their
'Java Developer's Handbook',Heller-Roberts
1. Create an IDL file that represents
the interfaces desired
2. Compile the IDL file using
idltojava
3. Compile the generated classes
using javac
4. Create an implementation class
5. Create the implementation server
6. Create the client application
(or applet)
7. Compile the implementation,
server and client code
8. Start the Naming Service application,
tnameserv
9. Start the server (which registers
with the Naming Service)
10. Start the client
1. Creating the IDL File
module Calculator{
interface Functions{
// idl interface is like java's
float square_root ( in float number );
float power ( in float base, in float exponent);
};
};
// java doesn't require the semi-colons after the curly
braces
The IDL file describes an IDL interface named Functions, enclosed in
the running scope of a
module named Calculator, describing a single service
(containing two operations).
2. Compiling the IDL File using the idltojava compiler // similar to RMI compiler
idltojava -fno-cpp calc.idl // save IDL to a file suffixed .idl
where -fno-cpp option turns off C/C++ preproccessing // translates flag no preprocessor
// the idltojava is written in native C++ (thus the preprocessor directives). The newer idlj is all java.
The compilation creates the following Java
files and directories
Calculator | The directory/package created by the module declaration |
Functions | A Java interface declaring operations as methods |
_FunctionsImplBase | An abstract class implementing 'Functions' providing
the server a
skeleton class from which it can inherit Corba connectivity. The server or an implementation object subclasses this skeleton and implements it's methods |
_FunctionsStub | Another class implementing the Functions interface,
the stub is
extended by the client to access the interface methods |
FunctionsHolder | A utility class holding a reference to assist in
'out' and 'inout'
method argumentation not implemented in Java |
FunctionsHelper | Autility class providing auxillary functions i.e.
the narrow( ) method
required to cast CORBA object refs to their proper types |
3. Compiling the Generated Classes
The IDL compiler produces Java source code files that next are run through the javac compiler
javac Calculator\*.java
The interface Functions created by the idltojava
compiler
package Calculator; public interface Functions extends org.omg.CORBA.Object{ float square_root(float number); float power(float base,float exponent); } |
4. Creating the Implementation Class
One of the classes created by the idltojava
compiler is created as an abstract class extending org.omg.CORBA.DynamicImplementation
and implementing the Functions interface.
As a result it only needs to be extended and
Function's methods have to be implemented.
Heller-Roberts implemetation class
/* Note:Convenience by Design
The abstract, complicated and CORBA wise _FunctionsImplBase
generated
by the idltojava compiler is provided for the Corba programmer to easily
extend */
package Calculator
public class FunctionsImpl extends _FunctionsImplBase{
public FunctionsImpl( ) {
// constructor not required but
recommended
}
// method implementation
public float square_root(float number){
return (float)Math.sqrt((double)number);
}
public float power(float base, float exponent){
return (float)Math.pow((double)base,(double)exponent);
}
}
5. Creating the Server // See finished client and servers in the example code provided
The server class registers the implementation object with the ORB and
Naming Service and provides
the connection implementation class. It begins by initializing an ORB
object, then creating a reference
to the the implementation class, FunctionsImpl. It also publishes a
name to reference the object with
the Naming Service.
6. Creating the Client
The client locates a reference to the Functions object using the Naming
Service. After creating an ORB
instance, it requests an object reference matching that created through
the NamingContext. This general
CORBA reference must be cast or
narrowed to the appropriate reference type via the Helper
class
narrow( ) method. The object is now a client side stub representing
an implementation of the interface.
This instance can be used by the client to reference the desired method
calls.
7. Compile the Implementation, Client and Server
javac FunctionsImpl.java CalculatorServer.java CalculatorClient.java
8. Start the Naming Service
tnameserv -ORBInitialPort 1050 // naming service default port number is 900
Creates the IOR Interoperable Object Reference
followed
by the current port number
The naming service outputs a long string called
the IOR (Interoperable Object Reference)
and the current port the naming service is on.
The IOR describes location (host,name IP address
etc.) and the services the object provides and
can be used to allow two ORB's to eliminate the
need for having the naming service locate the
object.
9. Start the Server
java CalculatorServer -ORBInitialPort 1050
-starting the server reisters the implementation object with the Naming
Service by using port number (exampled here) or by using the IOR
published at Naming Service start up.
10. Start the Client
java CalculatorClient -ORBInitialPort 1050
-if successful in locating the server and remotely referencing
the FunctionsImpl object's methods, the results from thesquare root
and power operations will be written to screen.