ICT337 Advanced Software Development

Murdoch University Topic 8

Topic 8
CORBA

·  What is CORBA?

·  How does it work?

·  Benefits of using CORBA ORBs

·  Java IDL

·  Writing a CORBA program (example 1)

·  IDL to Java mappings

·  CORBA examples 2 & 3

·  Callbacks in CORBA (example 4)

·  Images sent from client to server (example 5)

·  SII and DII

·  RMI vs CORBA

·  Summary

What is CORBA?

CORBA (the Common Object Request Broker Architecture) is a specification that enables distributed software components to work together regardless of the programming language used to develop them, the computer platform they run on, or the computer networks they use.

CORBA defines an abstract, inherently distributed object model and provides an infrastructure that enables invocations of operations on these objects as if they were local to the application using them.

CORBA is standardized on language bindings (or mappings) for: C, C++, Java, Ada, COBOL, Smalltalk, Objective C, Lisp.

The specification is written in a neutral Interface Definition Language (IDL). The IDL is used to create interfaces that all objects conforming to the CORBA specification can understand. The interfaces include the declaration of operations (equiv. to Java methods) that the CORBA objects support.

The CORBA Object Request Brokers (ORBs) use a protocol called the IIOP (Internet Inter-ORB Protocol), which is based on the standard TCP/IP protocol.

CORBA is a product of a consortium called the Object Management Group (OMG) that includes over 800 companies – except for Microsoft, which has its own competing object broker called the Distributed Component Object Model (DCOM).

CORBA 1.1 was released in 1991

CORBA 2 “ “ “ “ end of 1994

CORBA 3 “ “ “ “ end of 1999

CORBA implementation: The Java 2 ORB comes with jdk1.2.x

In this topic, we will focus only on CORBA/JAVA ORB from JavaSoft’s Java IDL for jdk1.3 and above.

Topic8.doc Page 2

ICT337 Advanced Software Development

Murdoch University Topic 8

How does it work?

Distributed CORBA objects are packaged as binary components that remote clients can access via method invocations.

The ORB is the object bus. It lets CORBA objects transparently make requests to, and receive responses from, other objects located locally or remotely – clients are not aware of the mechanisms used in the communication.

The concepts of stubs, skeletons, and ORBs between CORBA and RMI are the same. The only differences are:

·  the protocols used by the RMI ORB and CORBA ORB are JRMP and IIOP respectively (so RMI ORBs and CORBA ORBs cannot communicate).

·  the interfaces of CORBA objects are defined using a special language called IDL.

·  Java RMI supports server and client codes written in Java only.

Benefits of using CORBA ORBs

A CORBA ORB provides a wide variety of distributed middleware services. Below is a short list of benefits that every CORBA ORB provides:

·  Static and dynamic method invocations: A CORBA ORB lets you either statically define your method invocations at compile time or lets you dynamically discover them at run time.

·  High-level language bindings: A CORBA ORB lets you invoke methods on server objects using your preferred high-level programming language.

·  Built-in security and transactions: The ORB includes context information to handle security and transactions across machine and ORB boundaries.

·  Polymorphic messaging: in contrast to other forms of middleware, an ORB does not simply invoke a remote function – it invokes a function on a target object. Thus, the same function call will have different effects, depending on the object that receives it.

·  Local/remote transparency: in general, a CORBA client/server programmer does not have to be concerned with transports, server locations, byte ordering across dissimilar platforms, or target operating systems.


Java IDL

Java IDL is an Object Request Broker provided with the Java 2 Platform. Together with the idlj compiler, it can be used to define, implement, and access CORBA objects from the Java programming language.

Java IDL is compliant with the CORBA/IIOP 2.0 Specification and the IDL-to-Java Language Mapping.

Similar to the concepts in RMI, a CORBA object puts all its methods (including parameter types and exception thrown, if any) available to the clients in its interface. The interface is defined using the OMG Interface Definition Language (IDL). An IDL compiler (eg. idlj) translates the CORBA object definitions into a specific programming language according to the appropriate OMG language mapping.

The goal in CORBA object development is the creation and registration of an object server, or simply server. A server is a program which contains the implementation of one or more object types and which has been registered with the ORB.

(NOTE: idlj comes with jdk1.3. If you are using jdk1.2 then an IDL compiler called idltojava can be downloaded separately)
Writing a CORBA program

All CORBA objects support an IDL interface; the IDL interface defines an object type. An interface can inherit from one or more other interfaces.

A module in IDL is equivalent to a package in Java. A module groups interfaces together into their own namespace. An IDL interface declares a set of client accessible operations, exceptions, and typed attributes (values). Each operation has a signature that defines its name, parameters, result, and exceptions.

The CORBA IDL syntax is very similar to that of C++ and Java.

Writing a CORBA program involves the following steps:

1.  specify the interfaces (the IDL file)

2.  implement (Java coding) the methods declared in the interfaces

3.  write the CORBA server program (Java coding)

4.  write the CORBA client program (Java coding)


Step 1: specify the IDL module. Several interfaces can be grouped under an IDL module. Declare the methods available to the clients under each interface.

An example of an IDL module, Hello.idl:

module HelloApp {

interface Hello {

string sayHello();

};

};

The IDL compiler, idlj, translates IDL definitions into Java constructs according to the IDL-to-Java language mapping. In addition, it generates a stub file and a skeleton file for each object type.

Step 2: use idlj to create the stub, skeleton, and other associated files:

idlj –fall Hello.idl

The above command is equivalent to

idlj –fclient -fserver Hello.idl

which creates both the client- (stub) and server-side (skeleton) binding.

The idlj compiler creates 6 files under the subdirectory having the same name as the module name (here, the subdirectory is HelloApp). These files are: XXXPOA.java, _XXXStub.java, XXXHelper.java, XXXHolder.java, XXXOperations.java, XXX.java, where XXX is the interface name.

In the example above, we have

·  HelloPOA.java: this is an abstract Java class that implements the CORBA server-side skeleton for Hello. (In earlier versions of Java _HelloImplBase.java was created instead to play a similar role in a slightly different architecture)

·  _HelloStub.java: this is a Java class that implements the client-side stub for the Hello object. It is an internal implementation of the Hello interface that provides marshalling functions. Make sure you include this file with your client implementation.

·  HelloHelper.java: a helper class is a collection of static methods for a number of type-specific operations. These include narrowing (think about this as casting) object references to the correct interface type, marshalling and unmarshalling values to and from streams.

This is a Java class that provides useful helper functions for the Hello clients.

·  HelloHolder.java: to accommodate the passing of inout and out parameters in Java (which can pass arguments only by value), there are holder classes for IDL predefined (see the later section on “CORBA types”) and user-defined types. Holder classes are user-defined types that are generated by the IDL compiler. Holder classes for IDL predefined types are provided in the CORBA class library (package org.omg.CORBA).

This is a Java class that holds a public instance member of type Hello. It is used by clients and servers to pass objects of type Hello as out and inout parameters (see later) inside method invocations.

·  Hello.java: this is the Java version of Hello.idl. The content of the file is:

package HelloApp;

/**

* HelloApp/Hello.java .

* Generated by the IDL-to-Java compiler (portable), v

* from Hello.idl

* Saturday, 18 October 2003 08:19:15 PM WST

*/

public interface Hello extends HelloOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {

} // interface Hello

·  HelloOperations.java: this is the Java interface that embodies the declaration of the methods in Hello.idl

package HelloApp;

public interface HelloOperations {

String sayHello ();

}

Now we come to the server side implementation. We must define the methods declared in Hello.idl. The compiler idlj has created an abstract XXXPOA class that provides the basic functionality. What we need to do is inherit this class and include the extra methods we desire.

Step 3: write HelloImpl.java:

import HelloApp.*;

public class HelloImpl extends HelloPOA

{

public String sayHello()

{

return "\nHello world !!\n";

}

}

Every CORBA server must have some kind of main program that initializes the ORB environment and starts objects, so the next step is…

Step 4: write HelloServer.java:

import HelloApp.*;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

import org.omg.PortableServer.*;

import org.omg.PortableServer.POA;

import java.util.Properties;

public class HelloServer {

public static void main(String args[]) {

try {

// create and initialize the ORB

ORB orb = ORB.init(args, null);

// get reference to rootpoa

//& activate the POAManager

POA rootpoa = POAHelper.narrow(

orb.resolve_initial_references("RootPOA"));

rootpoa.the_POAManager().activate();

// create servant

HelloImpl helloImpl = new HelloImpl();

;

// get object reference from the servant

org.omg.CORBA.Object ref = root poa.servant_to_reference

(helloImpl);

Hello href = HelloHelper.narrow(ref);

// get the root naming context

org.omg.CORBA.Object objRef = orb.resolve_initial_references ("NameService");

// Use NamingContextExt

//which is part of the Interoperable

// Naming Service (INS) specification.

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

// bind the Object Reference in Naming

String name = "Hello"; NameComponent path[] = ncRef.to_name( name );

ncRef.rebind(path, href);

System.out.println

("HelloServer ready and waiting ...");

// wait for invocations from clients

orb.run();

} catch (Exception e)

{ System.err.println("ERROR: " + e); e.printStackTrace(System.out); }

System.out.println("HelloServer Exiting ...");

} }

}

Very often you will have to also write the client program for your clients and then make it available for the clients to use. Thus, the names of the objects that are bound on the name server are known to the client program (you). Below is HelloClient.java

Topic8.doc Page 2

ICT337 Advanced Software Development

Murdoch University Topic 8

Step 5: write HelloClient.java

import HelloApp.Hello;

import HelloApp.HelloHelper;

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 (Exception e) {

System.out.println("ERROR : " + e) ;

e.printStackTrace(System.out);

}

}

}

Step 6: compile all the Java class files:

javac HelloApp\*.java

javac HelloClient.java

javac HelloImpl.java

javac HelloServer.java

Step 7: execution:

·  start the name server in the first MS-DOS window using the tnameserv utility:

tnameserv –ORBInitialPort 1099

·  start the CORBA server in the second MS-DOS window:

java HelloServer –ORBInitialPort 1099

·  start the CORBA client in the third MS-DOS window:

java HelloClient –ORBInitialPort 1099


java HelloClient –ORBInitialPort 1099 –ORBInitialHost 123.4.5.6


If the client program is an applet rather than an application then the port number (and other settings, if appropriate) must be explicitly set in the applet or in the html file. Below is HelloApplet.java:

import HelloApp.Hello;

import HelloApp.HelloHelper;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

import java.awt.Graphics;

import java.util.Properties;

public class HelloApplet extends java.applet.Applet {

String message = "";

public void init() {

try {

String port = "1099";

System.out.println("Using ORBInitialPort = " + port);

// specify the port number by including it in the property list

Properties props = new Properties();

props.put("org.omg.CORBA.ORBInitialPort", port);

ORB orb = ORB.init(this, props);

// 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

message = helloRef.sayHello();

} catch (Exception e) {

System.out.println("HelloApplet exception: " + e.getMessage());

e.printStackTrace(System.out);

}

}

public void paint(Graphics g)

{

g.drawString(message, 25, 50);

}

}

The corresponding HTML file is:

·  Hello1.html

<html>

<head>

<title>Hello1 (CORBA client applet)</title>

</head>

<body>

<h1>Hello1.html</h1>

<applet codebase="." code=HelloApplet.class width=460 height=160>

</param>

</applet>

</body>

</html>

·  Hello2.html

<html>

<applet codebase="." code=HelloApplet.class width=460 height=160>

<PARAM name="org.omg.CORBA.ORBInitialHost" value="123.4.5.6">

<PARAM name="org.omg.CORBA.ORBInitialPort" value=1099>

</param>

</applet>

</body>

</html>

Topic8.doc Page 2

ICT337 Advanced Software Development

Murdoch University Topic 8

A few notes

·  Modularity in CORBA: All the 6 Java files (including the stub and skeleton files) under the HelloApp subdirectory are generated by the idlj compiler using the Hello.idl file as input; out of these 6 files only 4 are required by the client program, HelloClient.java or HelloApplet.java. Modifying the implementation in HelloImpl.java does not require these 6 files to be recompiled and reincorporated in the client code. (cf. RMI)

·  Low-level details omitted in coding:

o  idlj generates the stub and skeleton files for you; you only need to code Hello.idl, HelloImpl.java, HelloServer.java and the client program. If C++ rather than Java is desired then use a IDL-to-C++ compiler (eg. idl2cpp that comes with VisiBroker for C++ 3.1).

o  idlj also generates the Holder and Helper classes for each user-defined IDL interface, allowing you to call the methods defined in these classes without the need to study the detailed implementation.

·  See also the Hello-remote folder and the discussions on exportation of files of the server to the client.

CORBA types

IDL to Java mappings

CORBA IDL / Java
General Constructs
module / package
in parameters / normal Java parameters
out and inout parameters / Java Holder classes (generated by idlj and then instantiated by client side)
attribute / pair of methods
Exception / Exception
Primitive Types
const / public static final field
boolean, TRUE, FALSE (1-bit) / boolean, true, false (1-bit)
char (8-bits) / char (16-bits)
wchar (16-bits) / char (16-bits)
octet (8-bits) / byte (8-bits)
string, wstring / java.lang.String
short, unsigned short (16) / short (16)
long, unsigned long (32) / int (32)
long long,
unsigned long long (64) / long (64)
float (32) / float (32)
double (64) / double (64)
Fixed / java.math.BigDecimal
Constructed Types
interface / interface
sequence / array
array / array
struct / Java class with same name as struct type
enum / Java class with same name as enum type
typedef / Java does not have a typedef construct. Mapped to simple IDL types or user-defined IDL types
any / Java class org.omg.CORBA.Any

Java provides 16-bits for characters so that you can use the Unicode character standard