Given by Geoffrey Fox, Wojtek Furmanski, Nancy McCracken, Chao-Wei Ou, Shrideep Pallickara at Basic Information Track Computational Science Course CPS616 on Spring Semester 1999. Foils prepared May 19 1999
Outside Index
Summary of Material
This describes CORBA in general with a description of architecture including:
|
We describe development of an example with the Visigenic ORB |
We describe another example with JavaIDL ORB |
The Oject Management Architecture includes
|
We discuss the role of CORBA in a 3 tier distributed information system and describe role of Javabeans and use of CORBA and Javabeans to wrap existing applications |
Outside Index
Summary of Material
Geoffrey Fox, Wojtek Furmanski, Nancy McCracken, |
Chao-Wei Ou, Shrideep Pallickara |
NPAC at Syracuse University |
111 College Place, Syracuse NY 13244 4100 |
See resources listed at http://www.npac.syr.edu/projects/webtech/book |
http://www.npac.syr.edu/users/gcf/cps616corbafeb99/ |
This describes CORBA in general with a description of architecture including:
|
We describe development of an example with the Visigenic ORB |
We describe another example with JavaIDL ORB |
The Oject Management Architecture includes
|
We discuss the role of CORBA in a 3 tier distributed information system and describe role of Javabeans and use of CORBA and Javabeans to wrap existing applications |
OMG site: http://www.omg.org |
NPAC page with Java and CORBA books: http:// www.npac.syr.edu/projects/webtech/book/index.htm |
Collection of resources: http://acl.lanl.gov/CORBA |
Netscape CORBA and Crossware white papers: http://developer.netscape.com/library/wpapers/{crossware,corba}/index.html |
JavaIDL: http://www.javasoft.com/products/jdk/idl/ |
NPAC Java IDL tutorial: http://class-server.npac.syr.edu:3768/cwou/JavaIDL |
CORBA (Common Object Request Broker Architecture) is an Object Bus based distributed computing environment |
CORBA standards are developed since by OMG (Object Management Group) of some 500 companies (including IBM, Oracle, Sun, HP, Netscape) |
Cross-language support is provided by architecture-neutral IDL (Interface Description Language) |
Cross-platform support is provided by IDL->Native Language pre-compilers that generate platform-specific ORB servers, exporting IDL interfaces |
CORBA objects differ from typical programming language objects in these ways:
|
CORBA object developers need know nothing of where their clients will be, what hardware or OS they will run on, or what language they will be written in. |
CORBA objects approach universal accessibility. |
The diagram on the next slide (from the OMG CORBA architecture specification) illustrates the overall client/server architecture of CORBA.
|
In fact, distinction between CORBA clients and servers is transient and dynamic, i.e. each ORB on the CORBA bus can act as client and as server |
CORBA supports both static ("precompiled") and dynamic ("scripted") remote method invocation models |
Clients and Servers both have ORB capability |
In some sense |
CORBA is |
a server-server |
not |
client-server |
model |
Note it supports |
server object |
call-back to |
client object |
CORBA provides a uniform distributed object model |
Today we see a more complex distributed heterogeneous server (as proxy for service) model which we view as a 3 tier architecture on next foil |
COM from Microsoft is a similar model largely focused on PC's with a richer (in terms of implemented objects) current implementation but a less elegant architecture |
RMI from JavaSoft is cross platform distributed object model like CORBA but confined to one language (Java) whereas CORBA is multi-language and multi-platform |
W is Web Server |
PD Parallel Database |
DC Distributed Computer |
PC Parallel Computer |
O Object Broker |
N Network Server e.g. Netsolve |
T Collaboratory Server |
Clients |
Middle Layer (Server Tier) |
Third Backend Tier |
Clients invoke remote object |
Client |
Object Implementation |
Request |
ORB |
A client invokes a remote object by requesting to execute one of its methods. |
Client |
ORB Core |
ORB Dependent Interface |
IDL |
Stubs |
Request |
The client actually calls a surrogate method, called the stub, or constructs the request dynamically. The client must have an Object Reference for the remote object, know the type of the object and the method to be called. |
Dynamic |
invocation |
Object Implementation |
ORB Core |
ORB Dependent Interface |
ORB |
Interface |
Static IDL |
Skeleton |
Implementation |
Support Interface |
The ORB locates the implementation code, transmits parameters and transfers control to the implementation through a skeleton. The implementation may obtain some support services. |
IDL |
Definition |
Implementation |
Installation |
Stubs |
Skeleton |
Interface |
Repository |
Implementation |
Repository |
Client |
Object Implementation |
The IDL interface is in the repository and the definition is used to make stubs and skeletons. The object implmentation is stored in its repository. |
IDL is a language for defining what operations are available and how they should be invoked for each remote object.
|
IDL supports Object-Oriented concepts such as encapsulation, inheritance and polymorphism. |
Each language mapping of IDL should be the same for all ORB implementations. |
The language mapping includes language-specific data types and procedure interfaces. |
An IDL unit is called a module and contains a set of class interfaces containing attributes and methods (similar to Java interfaces with variables and methods.) |
module <identifier> |
{ |
<type declaration> |
<constant declaration> |
<exception declaration> |
interface <identifier> [:<inheritance>] |
{ |
<type declaration> |
<constant declaration> |
<exception declaration> |
[<op_type>] <identifier> (<parameters>) [raises exception] [context]; |
: |
}; |
interface <identifier> [:<inheritance>] |
: |
}; |
A client of an object has access to an object reference for the object, and invokes operations on the object. A client knows only the logical structure of the object according to its interface and experiences the behavior of the object through invocations. |
Java clients see objects and ORB interfaces through the perspective of the language mapping, bringing the ORB right up to the programmer's level. Clients are maximally portable. |
Client code has no knowledge of the implementation of the object or which ORB is used to access the implementation. |
An object implementation provides the semantics of the object, usually by defining data for the object instance and code for the object's methods. |
Often the implementation will use other objects or additional software to implement the behavior of the object. In some cases, the primary function of the object is to have side-effects on other things that are not formal CORBA objects.
|
Note (theoretically) that a client of one ORB (say JavaIDL) can access objects from other ORB's (say Visigenic) as IIOP provides interoperability. |
An Object Reference is the information needed to specify an object within an ORB. Both clients and object implementations have an opaque notion of object references, and thus are insulated from the actual representation of them. |
There are two ways to get a reference for a CORBA object:
|
The representation of an object reference handed to a client is only valid for the lifetime of that client. |
There is a distinguished object reference, the null reference, guaranteed to be different from all object references, that denotes no object. In Java, this is a Java null. |
The stubs and skeletons implement exactly the same set of remote interfaces as the remote object implementation. |
The stub forwards invocation requests to the remote object implementation via the ORB layer.
|
The skeleton
|
The GIOP defines a set of message formats and data formatting rules to facilitate ORB - ORB communication. |
The Common Data Representation (CDR), which is tailored to data types supported by IDL, handles inter-platform issues such as byte ordering and provides the standard for the machine-independent representation. |
The GIOP specification defines a set of message formats that support all of the ORB request/reply semantics. |
Also defines format for Interoperable Object References (IOR), created whenever an ORB passes an object reference across ORB's. |
This is the protocol for sending GIOP messages between ORB's. |
To ensure "out-of-the-box" compatibility, the IIOP specification requires that ORB's send GIOP messages over TCP/IP. |
Using IIOP, can CORBA client can speak to any other CORBA object in a way that is location transparent. |
Object Adapters allow the object implementation to access services. The interface is unique for a particular ORB. |
Object Adapters are on the server side and may provide the following functionalities:
|
The naming service is one of the Common Object Services (COS). It provides a tree-like directory for object references. |
Each name/object reference pair is called a binding. |
Name bindings are organized into naming contexts, and are themselves bindings. |
All bindings are stored in the initial naming context, which can be obtained from the ORB on either the client or the server. |
The Implementation Repository contains information that allows the ORB to locate and activate implementations of objects. |
Ordinarily, installation of implementations and control of policies related to the activation and execution of object implementations is done through operations on the Implementation Repository. |
In addition to its role in the functioning of the ORB, the Implementation Repository is a common place to store additional information associated with implementations of ORB objects. (e.g., debugging information, administrative control, resource allocation, security, etc) |
The Implementation Repository supports the implementation of object servers. It is not needed by clients in order to access servers. |
To statically invoke an operation on a CORBA object, a client needs two things:
|
Of these, the client developer is only interested in the object reference; the stub class is generated automatically and its instances are created and invoked automatically. |
CORBA dynamic invocation uses an object called a request to hold everything pertinent to an invocation: the object reference, the name of the operation, its parameters, and space for the result. The client builds a request object describing an operation, then calls the request's invoke method, which dispatches the request just as a stub would. When the invoke method returns, the result is available in the request object. |
The key to dynamic invocation is the ability of requests to hold self-describing data. This facility enables a request object to represent any invocation of any operation, regardless of its parameters are. |
Note that under dynamic invocation, the existence of a server skeleton does not necessarily imply the existence of a client. |
To create a Java object you use the new() operator; to delete a Java object you do nothing; the garbage collector reclaims it for you. CORBA clients never create CORBA objects, only servers do. |
As a client, to create a CORBA object, you invoke another object which is the factory for the type of object you want created; the factory returns an object reference for you to use to invoke the new object. Typically the factory is implemented by the same server that implements the object type. |
Neither is there any standard way to delete a CORBA object. Because a CORBA object may be shared by many clients around a network, it is hard to know when an object has, in Java terms, become garbage. In general, only the object server is in a position to know, and then only if the server developer provides a "destroy" operation for the object. |
A transient CORBA object has the same lifetime as the execution of the server process that creates it. When a server terminates, its transient objects disappear with it. Transient objects are often used to effect asynchronous communication between applications and objects. |
By contrast, a persistent object lives until it is explictly destroyed. If a client has a reference to a persistent CORBA object, that reference can be used even if the object's server is not running--an ORB will start the server when it (the ORB) receives an invocation on the object. |
At present, Java IDL ORB supports only transient object servers, while others like Visigenic supports both. |
Client programs often need to react to changes or updates that occur on the server, such as changes in stock price. The client can either
|
The second option is called a callback. |
In CORBA, you can create two interfaces in one module:
|
Writing a Java CORBA example |
with the Visigenic ORB |
Count.java |
CountHelper |
CountHolder |
Stub |
_CountImplBase |
Skeleton |
Template |
Implementation |
CounterClient |
CountImpl |
CounterServer |
idltojava compiler |
User implements |
User |
IDL interface |
Count.idl |
ORB Core |
Client |
Server |
We will build CORBA object for the Count class using Visigenic VisiBroker ORB on the server, to be used for timing the client/server communication overhead in CORBA |
We will use Visigenic ORB on the client which is packaged in every Netscape communicator and so can be driven simply from applets |
The following code elements are displayed:
|
<<interface>> Count |
filter ( ) |
_st_ Count |
_ids ( ) |
filter ( ) |
_CountImplBase |
_CountImplBase ( ) |
_CountImplBase ( ) |
_ids ( ) |
_methods ( ) _execute ( ) |
_ execute ( ) |
_example_ Count |
_example_Count ( ) |
_example_Count ( ) |
filter ( ) |
_sk_ Count |
_sk_Count ( ) |
_sk_Count ( ) |
_CountHelper |
narrow ( ) |
bind ( ) |
_orb ( ) |
read ( ) |
write ( ) |
insert ( ) |
extract ( ) |
type ( ) |
id ( ) |
. . . |
The first step in the CORBA object development process is to specify the object in IDL |
IDL looks like a static subset of C++ |
Atomic IDL unit is called a module and it contains a set of class interfaces |
Class interfaces contain attributes and methods (similar to Java interfaces) |
Method arguments can be scalars, vectors, or sequences of scalars, vectors or lists (but not general objects, at least in CORBA 2.0) |
Module Counter { |
interface Count { // our object |
attribute long sum; // current count value |
long increment(); // does sum++ |
}; |
} |
Note: this code is provided by developer and |
passed to IDL->XXX language pre-compiler |
IDL->Native Language pre-compiler takes IDL specification as input and generates a suite of auxiliary and/or temporary files |
These intermediate files are ORB and Native Language dependent |
For example, if Native language is Java, pre-compiler generates Java interface for each IDL interface (next foil) by following IDL->Java mapping rules |
Both client and server codes are using this Java interface to refer to the object implementation |
IDL->Java pre-compiler is called: idl2java |
boolean |
char/wchar |
octet |
string/wstring |
short/unsigned short |
long/unsigned long |
long long/unsigned long long |
float |
double |
boolean |
char |
byte |
java.lang.String |
short |
int |
long |
float |
double |
IDL Type |
Java Type |
module |
interface |
enum |
struct |
union |
sequence/array |
any |
exception |
typedef |
package |
interface with an additional helper |
final class with enum values |
final class with the same name |
final class with the same name |
array |
class CORBA.any |
class extends CORBA.UserException |
Use original name |
IDL Type |
Java Type |
package Counter; |
public interface Count extends org.omg.CORBA.Object { |
/* Attribute Writer */ |
public void sum(int sum); |
/* Attribute Reader */ |
public int sum(); |
/*Implement Remote Operation */ |
public int increment(); |
} |
Note: The IDL type long was converted to Java type int |
Note: This code is created automatically by IDL->Java pre-compiler from the IDL spec |
Note: All client programs invoking the remote count object must use this as interface definition for remote object |
A Java interface (as seen on previous slide) |
A Java class that defines auxiliary methods, notably narrow(), which is the CORBA counterpart of Java casting. The class is called ---Helper, where --- is your application name. |
A Java class which defines methods for setting and getting the values of holders. Holders are required for CORBA operations that take out or inout arguments, which, unlike CORBA in arguments don't map directly to Java's call-by-value semantics. |
The _example_---, a template class for the implementation. |
The stubs and skeletons. |
Another auxiliary file generated by IDL->Java pre-compiler is client-side stub (here called _st_Count) |
It implements Count interface and extends org.omg.CORBA.portable.ObjectImpl superclass |
Count methods and attribute accessors are implemented by opening CORBA runtime libraries implementing I/O, submitting the invocation request to the server, retrieving the results from the stream, and returning to the client |
package Counter; |
public class _st_Count extends org.omg.CORBA.portable.ObjectImpl implements Counter.Count { |
public int increment() { try { |
org.omg.CORBA.portable.OutputStream _output = this._request("increment",true); /* Call Remote Object */ |
org.omg.CORBA.portable.InputStream _input = this._invoke(_output, null); /* Detect Answer */ |
int _result; _result =_input.read_long(); /* Returned value */ |
return _result; } |
catch(org.omg.CORBA.TRANSIENT _exception) { |
return increment(); } } |
public int sum() { ... } |
Note: This code is created automatically by IDL->Java pre-compiler from the IDL spec and is a fragment of full stub that implements all methods |
Also note that, unlike RMI, the Stub is in java and can be read by the developer. |
There is a "base" server side Count object _CountImplBase which is used to implement by different extensions, both the skeleton and the actual object. |
A server-side skeleton, here called _sk_Count, plays similar role to the client stub but at the server side, i.e. handles remote method invocation |
Skeleton implements Count in terms of the generic _execute method of the org.omg.CORBA.portable.Skeleton object |
_execute is called with the methodId value that uniquely identifies a given method |
_execute is implemented as a switch which jumps to the appropriate method implementation |
the actual method execution is performed by CountImpl instance, passed as _self argument |
package Counter; |
abstract public class _sk_Count extends _CountImplBase { |
protected _sk_Count(java.lang.String name) { |
super(name); |
} |
protected _sk_Count() { |
} |
} |
Note: This code is created automatically by |
IDL->Java pre-compiler from the IDL spec |
This is generated automatically from IDL and is extended by both skeleton and example implementation template |
abstract public class _CountImplBase extends org.omg.CORBA.portable.Skeleton implements Counter.Count { |
public static boolean _execute(Counter.Count _self, int _method_id, org.omg.CORBA.portable.InputStream _input, org.omg.CORBA.portable.OutputStream _output) { switch(_method_id) { |
case 0: { |
int _result = _self.increment(); /* Increment and return result */ |
_output.write_long(_result); return false; } |
case 1: { |
int sum; |
sum = _input.read_long(); /* Set value of sum */ |
_self.sum(sum); return false; } ................. } |
IDL->Java preprocessor also generates the server-side implementation template for the object under construction |
The user needs only to:
|
Note that the pre-compiler generates two accessor methods (for set and get operations) for each object attribute specified by IDL |
package Counter; |
public class _example_Count extends Counter._CountImplBase { |
/** Construct a persistently named object. */ |
public _example_Count(java.lang.String name) { |
super(name); |
} |
/** Construct a transient object. */ |
public _example_Count() { |
super(); |
} |
Note: This code is generated by IDL->Java pre-compiler and needs to be |
completed by the developer (by implementing the indicated methods) |
public int increment() { // implement operation... return 0; } |
public void sum(int sum) { // implement attribute writer... } |
public int sum() { // implement attribute reader... return 0; } } // End _example_Count |
Implementer must complete these methods as CountImpl.java |
Finally, we provide the server-side implementation of the object under construction, here given by the CountImpl class |
It is constructed by completing the implementation template as discussed in the previous three foils |
Remember that our Count is in fact a very simple object: it maintains a counter value called sum and it increments it whenever its increment() method is invoked |
public class CountImpl extends Counter._CountImplBase { |
private int sum; |
public CountImpl(java.lang.String name) { // Construct a persistent object. |
super(name); sum=0; |
System.out.println("Count Object Created"); } |
public CountImpl() { // Construct a transient object |
super(); } |
public int increment() { // Implementation of remote operation |
sum++; |
return sum; } |
public void sum(int val) { // implement attribute writer... |
sum = val; } |
public int sum() { // implement attribute reader... |
return sum; } |
} |
The main server program performs the following operations:
|
class CountServer |
{ static public void main(String[] args) |
{ try { // Initialize the ORB. |
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); |
org.omg.CORBA.BOA boa = orb.BOA_init(); // Initialize the BOA. |
// Create the Coordinator object. |
CountImpl _count = new CountImpl("Counter"); |
boa.obj_is_ready(_count); // Export the newly created object. |
System.out.println("Exported " + _count); |
System.out.println("CountImpl waiting for requests"); |
boa.impl_is_ready(); } |
catch(org.omg.CORBA.SystemException e) |
{ System.err.println(e); } |
} } |
Note: This code is created by the developer |
public class |
CountClient extends Applet { |
................... Method to Initialize .................... |
private void connectToCountObject() { |
// Initialize the ORB. |
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(this); |
// Calculate Start time |
long startTime = System.currentTimeMillis(); |
counter = Counter.CountHelper.bind(orb, "Counter"); |
long stopTime = System.currentTimeMillis(); |
System.out.println("Avg time to setup Orblet = " |
+ ((stopTime - startTime)/1000f) + " secs"); |
} |
} |
The main client program is an applet (because we are using Visigenic which is supported by Netscape browser) and processes button clicks which include
|
Count.idl -- the IDL |
_st_Count.java the Stub |
_CountImplBase.java The Base Implementation |
_sk_Count.java The Skeleton |
_example_Count.java Example Server Side Object |
CountServer.java Server Side Manager |
CountImpl.java Server Side Count object |
CountClient.java Client program invoking remote Count object |
There are additional files generated by the precompiler (on next slides). |
Generated by pre-compiler |
} |
Support for out and inout parameter passing modes requires the use of additional "holder" classes. |
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 user defined IDL types, the holder class name is constructed by appending Holder to the mapped (Java) name of the type. |
For the basic IDL datatypes, the holder class name is the Java type name (with its initial letter capitalized) to which the datatype is mapped with an appended Holder, e.g. IntHolder. |
Each holder class has a constructor from an instance, a default constructor, and has a public instance member, value, which is the typed value. |
The default constructor sets the value field to the default value for the type as defined by the Java language:
|
In order to support portable stubs and skeletons, holder classes for user defined types also have to implement the org.omg.CORBA.portable.Streamable interface. |
The holder classes for the basic types are illustrated on next foil. Note that they do not implement the Streamable interface. They are in the org.omg.CORBA package. |
package org.omg.CORBA;
|
The Holder class for a User defined type foo
|
All user defined IDL types have an additional "helper" Java class with the suffix Helper appended to the type name generated. |
Several static methods needed to manipulate the type are supplied. These include Any insert and extract operations for the type, getting the repository id (bind), getting the typecode, and reading and writing the type from and to a stream. |
For any user defined IDL type, the following is the Java code generated for the type. |
In addition, the helper class for a mapped IDL interface also has a narrow operation defined for it. |
OMG IDL supports inheritance; the top of the hierarchy is Object in OMG IDL, org.omg.CORBA.Object in Java. (Note that both CORBA and Java define Object, but they are the tops of different type hierarchies.) |
Some operations, notably name lookup and unstringifying, return org.omg.CORBA.Objects, which you narrow (using a helper class generated by idltojava) to the derived type you want the object to be. CORBA objects must be explicitly narrowed because the Java runtime cannot always know the exact type of a CORBA object. |
public class fooHelper {
|
// only for interface helpers |
public static narrow(org.omg.CORBA.Object obj); |
} |
At the current time, Visibroker for Java 2.5 (on the server side) has a matching ORB embedded in Netscape Communicator:
|
To use Visibroker for Java 3.0, download the ORB to the browser:
|
Using an Imaging example (which has an array argument and result) |
Same Machine Different M/cs Same Machine Different M/cs |
CORBA |
RMI |
Initialize the ORB |
Bind the Remote Object |
Invoke and Complete Remote Operation |
393 ms |
40 ms |
1.263 s |
475 ms |
180 ms |
1.743 s |
200 ms |
246 ms |
614 ms |
744 ms |
Writing a Java CORBA example |
with the JavaIDL ORB |
This is a "JORB" -- a Java server implementation of CORBA. |
This ORB is available in JDK1.2 |
The Java IDL ORB is not production quality (because of omitted features) but can be used to develop Java language CORBA objects which can then be used with other more sophisticated ORB's in production mode.
|
The main difference between this ORB and the Visigenic ORB is that this ORB uses the Naming Service to bind the remote object, instead of the Basic Object Adapter. |
module HelloApp |
{ |
interface hello; |
{ |
string sayHello(); |
}; |
}; |
To use idltojava to compile the "hello" example IDL code as |
idltojava -fclient -fserver hello.idl |
Two sets of Java codes will be generated:
|
To implement a server for transient CORBA objects of some type, you write a Java class called a servant, which inherits from a class called the servant base; servant base classes are optionally generated by the idltojava compiler. |
An instance of a transient CORBA object is implemented by an instance of its servant class. |
The servant base class is the CORBA type-specific interface between the ORB and the servant code for the type. It unmarshals incoming parameters, invokes servant methods, marshals results, and directs the ORB to return results to the client ORB. |
A servant class extends its servant base with a method for each operation in the IDL interface definition it implements. |
The example server consists of two classes, the servant and the server. |
The servant, HelloServant, is the implementation of the Hello IDL interface. |
Each Hello instance is implemented by a HelloServant instance. |
The servant is a subclass of _HelloImplBase, which is generated by the idltojava compiler from the example IDL. |
The servant contains one method for each IDL operation. |
import HelloApp.*; |
import org.omg.CosNaming.*; |
import org.omg.CosNaming.NamingContextPackage.*; |
import org.omg.CORBA.*; |
class HelloServant extends _HelloImplBase |
{ |
public String sayHello() |
{ |
return "\nHello world !!\n"; |
} |
} |
Creates an ORB instance |
Creates a servant instance (the implementation of one CORBA Hello object) and tells the ORB about it |
Gets a CORBA object reference for a naming context in which to register the new CORBA object |
Registers the new object in the naming context under the name "Hello" |
Waits for invocations of the new object |
public class HelloServer { |
public static void main(String args[]) { |
try{ |
// create and initialize the ORB |
ORB orb = ORB.init(args, null); |
// create servant and register it with the ORB |
HelloServant HelloRef = new HelloServant(); orb.connect(HelloRef); |
// get the root naming context |
org.omg.CORBA.Object objRef = |
orb.resolve_initial_references("NameService"); |
NamingContext ncRef = NamingContextHelper.narrow(objRef); |
// bind the Object Reference in Naming |
NameComponent nc = new NameComponent("Hello", ""); |
NameComponent path[] = {nc}; ncRef.rebind(path, HelloRef); |
// wait for invocations from clients |
java.lang.Object sync = new java.lang.Object(); |
synchronized (sync) { |
sync.wait(); |
} |
. . . // catch exceptions |
} |
The example application client that follows: |
Creates an ORB |
Obtains a reference to the naming context |
Looks up "Hello" in the naming context and receives a reference to that CORBA object |
Invokes the object's sayHello() operation and prints the result |
import HelloApp.*; |
import org.omg.CosNaming.*; |
import org.omg.CORBA.*; |
public class HelloClient { |
public static void main(String args[]) { |
try{ // create and initialize the ORB |
ORB orb = ORB.init(args, null); |
// get the root naming context |
org.omg.CORBA.Object objRef = |
orb.resolve_initial_references("NameService"); |
NamingContext ncRef = NamingContextHelper.narrow(objRef); |
// resolve the Object Reference in Naming |
NameComponent nc = new NameComponent("Hello", ""); |
NameComponent path[] = {nc}; |
Hello HelloRef = HelloHelper.narrow(ncRef.resolve(path)); |
// call the Hello server object and print results |
String Hello = HelloRef.sayHello(); |
System.out.println(Hello); |
} . . . // catch exceptions |
} |
The server exports two methods InitSum and Increment methods simply initialize variable sum and increments it by one, respectively. Then it returns the value of sum to the client. |
The Client increments the sum to 1000 and keeps tracking of the elapsed time. The output is the average time per increment. (Roughly, this can be treated as the average time for ping command on IIOP.) |
module Counter{ |
interface Count { |
attribute long sum; |
void initSum(in long value); |
long increment(); |
}; |
}; |
Note: This code is provided by developer and passed to idltojava pre-compiler |
Client's classes:
|
Server's Classes:
|
Count |
CountHelper |
CountHolder |
_CountStub |
_CountImplBase |
(Skeleton and |
Implementation) |
CounterClient |
CountServantImpl |
CounterServer |
idltojava compiler |
User implements |
Counter IDL |
ORB Core |
Client |
Server |
package Counter; |
public interface Count extends org.omg.CORBA.Object { |
int sum() throws org.omg.CORBA.SystemException; |
void sum(int arg) throws org.omg.CORBA.SystemException; |
void initSum(int value); |
int increment(); |
} |
Note: This code is created automatically by idltojava pre-compiler from the IDL spec. |
package Counter; |
public class _CountStub extends org.omg.CORBA.portable.ObjectImpl implements Counter.Count { |
...... |
public int sum() throws org.omg.CORBA.SystemException { |
long _n[] = new long[1]; |
java.lang.Object _o[] = new java.lang.Object[1]; |
_invoke(__ops[0], _n, _o); |
return (int) (_n[0] & 0xFFFFFFFFL); |
} .... |
package Counter; |
public final class CountHelper { |
// It is useless to have instances of this |
class private CountHelper() { } |
public static void __write(org.omg.CORBA.portable.OutputStream out, Counter.Count that) { |
out.write_Object(that); |
} |
..... |
package Counter; |
public final class CountHolder implements org.omg.CORBA.portable.Streamable{ |
// instance variable |
public Counter.Count value; |
// constructors |
public CountHolder() { |
this(null); |
} |
public CountHolder(Counter.Count __arg) { .... |
package Counter; |
public abstract class _CountImplBase |
extends org.omg.CORBA.portable.ObjectImpl |
implements Counter.Count, org.omg.CORBA.portable.Skeleton { |
static private org.omg.CORBA.portable.OperationDescriptor[][] _dispatch_table; |
static { |
_dispatch_table = new |
org.omg.CORBA.portable.OperationDescriptor[1][0]; |
......... |
The following packages used in developing the Counter/Timer example for both client and server codes: |
import java.io.*; |
import java.net.*; |
import org.omg.CORBA.*; |
import com.sun.CORBA.iiop.*; |
import org.omg.CosNaming.*; |
import org.omg.CosNaming.NamingContextPackage.*; |
import Counter.*; |
public class CounterClient |
{ |
public static org.omg.CORBA.ORB orb; |
public static Counter.Count counter; |
public static void main (String args[]) { |
try { |
orb = org.omg.CORBA.ORB.init(args, null); |
org.omg.CORBA.Object objRef = |
orb.resolve_initial_references("NameService"); |
NamingContext ncRef = |
NamingContextHelper.narrow(objRef); |
NameComponent nc = new |
NameComponent("Counter", ""); |
NameComponent path[] = {nc}; |
counter = |
Counter.CountHelper.narrow(ncRef.resolve(path)); |
counter.initSum((int)0); long startTime = System.currentTimeMillis(); for (int i=0; i i++) ; { counter.increment(); } long stopTime = System.currentTimeMillis(); System.out.println("Avg Ping = " + ((stopTime-startTime)/1000f) + "msecs"); System.out.println("Sum = " + counter.sum()); } ...// catch exceptions } |
class CountServantImpl extends Counter._CountImplBase { |
private int sum_; |
public CountServantImpl() { |
System.out.println("Count Object Created"); |
sum_ = 0; |
} |
public int sum() { |
return this.sum_; |
} |
public void initSum(int value) { |
sum(value); |
} |
public int increment() { |
this.sum_++; |
return this.sum_; |
} |
} |
public class CounterServer { |
public static org.omg.CORBA.ORB theORB; |
static public void main(String[] args) { |
try { |
theORB = org.omg.CORBA.ORB.init(args, null); |
CountServantImpl servant = new CountServantImpl(); |
theORB.connect(servant); |
org.omg.CORBA.Object objRef = |
theORB.resolve_initial_references("NameService"); |
NamingContext ncRef = NamingContextHelper.narrow(objRef); |
NameComponent nc = new NameComponent("Counter", ""); |
NameComponent path[] = {nc}; |
ncRef.rebind(path, servant); |
java.lang.Object sync = new java.lang.Object(); |
synchronized (sync) { |
sync.wait(); |
} |
} . . . //catch exceptions |
} |
Previous slides illustrated software components involved in enabling remote method invocation for a single object |
The next diagram categorizes various objects plugged in and playing on the CORBA bus |
The system itself (i.e. ORB vendors) provides a set of base object services the Common Object Services layer and high level facilities
|
Application objects built by users can refer to CORBA services/facilities as distributed OO libraries |
The strength of CORBA stems from a solid core, augmented by a broad family of standardized interfaces, developed over the last 7 years by OMG |
The core layer is given by the ORB model and the associated support to enable remote object invocation |
On top of the ORB layer, CORBA offers the Common Object Services (COS) layer |
On top of the COS layer, CORBA offers Common (Horizontal) and Vertical Market Facilities |
The whole collection is functionally equivalent to an object-oriented distributed operating system |
At present, the following Services are fully specified and published:
|
Externalization - the same as Serialization in Java |
Query - search in the object space |
Collection - operations on the query results |
Relationship - building relations among objects |
Licensing - support for object licensing |
Time - support for synchronized global clock |
CORBA Facilities are high level software concepts that build on top of Services |
Facilities split into Horizontal (general purpose) and Vertical (market specific) segments |
At the moment, most facilities are at the level of requirement specifications or Requests for Proposals |
The OMG process of specifying Services and Facilities is ongoing, never ending and reflecting the software technology evolution |
In the following, we list the major Facilities, discussed in the recent OMG publication |
User Interface
|
Information Management
|
System Management |
Task Management
|
Vertical Market Facilities
|
WorkFlow |
ORB |
System Management |
Computation? |
.............. |
Trader |
Security |
.......... |
Naming |
Persistence |
Oil & Gas |
DMSO Modeling and Simulation |
Imagery |
Banking |
Manufacturing |
...... |
...... |
Services |
Horizontal Facilities |
Vertical |
Facilities |
Standard Interfaces |
i.e. Frameworks |
Middle Tier |
Basic Web Server |
Custom Web Server |
TP Server |
Business Transaction Management |
You Write Software |
at Client and Server |
Old and New Useful Backend Software |
Client Applet |
with JDBC and user (form) |
interface |
Oracle Database |
Java Socket |
Oracle Driver |
OCI |
Client with Applet Javabean |
Vendor Specific |
Object Broker |
Object |
Database |
IIOP |
Custom |
CORBA |
Within the Sun philosophy of '100% Java', distributed objects can be developed using RMI interconnect. However, the rest of the industry tries to protect their C++ investments while converting to Java in new applications. |
Hence, in parallel with Java development, the Web industry explores now the linkage of Java with CORBA based distributed object technologies which offer an full C++/Java interoperability. |
CORBA supports cross-language remote object invocation as well as IIOP (Internet Inter-ORB Protocol) based interoperability between object brokers from various vendors. |
Java is a wonderful language with which to develop object brokers |
Of particular interest are Java based ORBs or ORBlets which can be downloaded as applets to enable CORBA capabilities also at the client/browser side. |
An alternative, offered by Netscape, is a resident ORB support in all browser and server products. |
Java based ORBs will soon turn the Web, so far acting as a largely passive document publishing framework, into a powerful dynamic world-wide distributed object-based computing environment. |
This implies servers that combine role of Web Servers and object brokers and link HTTP RMI and IIOP protocols (and perhaps also COM!) |
The current incoherent but highly creative Web will merge with distributed object technology in a multi-tier client-server-service architecture with Java based combined Web-ORB's |
COM(Microsoft) and CORBA(world) are competing cross platform and language object technologies
|
Need to abstract entities (Web Pages, simulations) and services as objects with methods(interfaces) |
How do we do this while infrastructure still being designed! |
One can anticipate this by building systems in terms of Java objects e.g. develop Web-based databases with Java objects using standard JDBC (Java Database Connectivity) interfaces |
Even better use Javabeans which are Java's componentware offering visual interfaces, containers (here they are consistent with CORBA standard) and standard software engineering interfacing rules |
They are Java's implementation of "component-based" visual programming |
This modern software engineering technique produces a new approach to libraries which become a "software component infrastructure(SCI)" |
There is a visual interface to discovery of and setting of values of and information about parameters used in a particular software component |
JavaBeans uses the event model of JDK1.1 to communicate between components
|
One expects Javabeans to become the CORBA component interface (defining containers in CORBA) |
The visual interface allows inspection of and implementation of both individual beans and their linkage . This visual construction of linkage allows one to form nontrivial programs with multiple communicating components
|
Apart from the event mechanism which is a communication/linkage mechanism, ComponentWare (and JavaBeans in particular) "just" give a set of universal rules (needed for interoperability) for rather uncontroversial (albeit good) object-oriented and visual programming practices
|
CORBA is natural distributed object formalism |
Java (with visual interfaces i.e. JavaBeans) is natural interface language
|
Linking this to tier 3 "classic applications" gives rise to JavaBean/CORBA wrappers for existing applications |
This turns legacy applications into CORBA distributed objects and so can be remotely executed and documented (via CORBA trader or yellow pages service) |
Further these applications now have a visual interface for linking them together in containers and inspecting their parameters |
A 2 Tier implementation is shown above |
The CORBA wrapper uses IDL for language of original (legacy) application (use CORBA C IDL for Fortran) |
One designs an IDL to reflect "application class" and re-uses it for several elated applications |
Javabean frontend can be same for each application class |