| OHSWG | 12.15.97 |

Open Hypermedia Systems Working Group
CORBA
This simple example is taken from Client/Server Programming with Java and CORBA by Robert Orfali and Dan Harkey. The goal of the example is to develop a simple counter application. The server object maintains a counter which can be incremented by its clients. In the book, the example serves several purposes. First, it is easily understood and allows the reader to focus on the component technology being used. Second, round-trip network performance (e.g. a ping) for the component technology can be roughly measured by having the client invoke the server n times and computing the elapsed time divided by n. (In the book, Java-based CORBA technologies averaged 3.4 milliseconds using a JIT compiler, 6.3 msecs without.)
The first step in using CORBA is defining a component's interface. This is accomplished by writing an IDL file. The IDL for the counter server is (example code on this page is Copyright © Robert Orfali and Dan Harkey, 1997):
module Counter {
interface Count {
attribute long sum;
long increment();
};
};
This file defines an interface called Count within a CORBA module called Counter. A module is similar to Java's package construct, while an interface defines a CORBA component. In the example above, the Count component has one attribute (e.g. instance variable) called sum which is of type long. Count has one method called increment which returns the current value of sum after incrementing it by one.
The next step in the CORBA process is to compile this file using an IDL compiler. The IDL compiler will generate a set of files which varies depending on the target programming language. Most IDL compilers produce C++ files, however compilers which target Java, SmallTalk, and (possibly?) Ada are also available. Regardless of the language, the IDL compiler produces at a minimum two files known as the skeleton and the stub.
The skeleton is a server-side file that defines a class that enables a CORBA component to be accessed by CORBA clients. Essentially this class encapsulates the details of connecting the server to the network (thereby making its presence known) and communicating with its clients. A server implementation typically subclasses the skeleton class, inheriting its functionality, and provides code to implement the operations defined by the IDL file. An example implementation of the Count component is shown below:
class CountImpl extends Counter._sk_Count implements Counter.Count {
private int sum;
// Constructor
CountImpl(String name) {
super(name);
System.out.println("Count Object Created.");
sum = 0;
}
// get sum
public int sum() throws CORBA.SystemException {
return sum;
}
// set sum
public void sum(int val) throws CORBA.SystemException {
sum = val;
}
//increment method
public int increment() throws CORBA.SystemException {
sum++;
return sum;
}
}
The above class is an example of a Java implementation of the Count component. It was developed to be used with VisiBroker for Java from Visigenic. The CountImpl class inherits from the _sk_Count class which is generated by the VisiBroker IDL compiler. As you can see, the _sk_Count class completely hides protocol details from the CountImpl server class. CountImpl instead focuses on implementing the interface specified by the IDL file. It declares a variable called sum which is initialized in the constructor. It provides an implementation for the increment operation, and implements getter and setter methods for the sum attribute. The Counter.Count interface, which CountImpl implements, serves two purposes: (1) it specifies the operations that CountImpl are required to implement in order to be a valid implementation of the Count interface and (2) it enables queries to take place dynamically at runtime to determine if a particular server object implements the Count interface.
The next step is to create a server program which initializes CORBA's runtime services, instantiates an instance of the Count component and makes it available for processing. The sample code below is specific to VisiBroker for Java and will not be discussed.
class CountServer {
static public void main(String[] args) {
try {
//Initialze the ORB
CORBA.ORB orb = CORBA.ORB.init();
// Initialize the Basic Object Adaptor
CORBA.BOA boa = orb.BOA_init();
// Create the Count component
CountImpl count = new CountImpl("My Count");
// Export to the ORB the newly created object
boa.obj_is_ready(count);
// Ready to service requests
boa.impl_is_ready();
} catch (CORBA.SystemException e) {
System.err.println("" + e)
}
}
}
At this point, the server-side work is complete!
We can now return to the stub class. The stub class is a client-side file which provides clients with the interface they require to connect to a CORBA component and invoke the services provided by the component's interface. Below is an example that demonstrates a client obtaining an object reference to a Count server and then using that reference to make calls on the server.
class CountClient {
public static void main(String args[]) {
// Initialize the ORB
System.out.println("Initializing the ORB");
CORBA.ORB orb = CORBA.ORB.init();
// Bind to the Count Component
System.out.println("Binding to the Count Component");
Counter.Count counter = Counter.Count_var.bind("My Count");
// Set sum to initial value of 0
System.out.println("Setting sum to 0");
counter.sum((int)0);
// Calculate Start time
long startTime = System.currentTimeMillis();
// Increment 1000 times
System.out.println("Incrementing...");
for (int i = 0; i < 1000; i++ ) {
counter.increment();
}
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = " +
((stopTime - startTime)/1000f) + " msecs");
System.out.println("Sum = " + counter.sum());
} catch (CORBA.SystemException e) {
System.err.println("" + e);
}
}
In order to run this example, a developer using the VisiBroker for Java CORBA environment would perform the following steps:
% osagent & % java CountServer & % java CountClient Initializing the ORB Binding to the Count component Setting Sum to 0 Incrementing... Avg Ping = 3.455 msec Sum = 1000
The osagent is part of the VisiBroker for Java system which acts essentially as a nameserver for CORBA components. The CountImpl class will register itself with the osagent and the CountClient will connect to the CountImpl component by asking the osagent where it is located. All of this is hidden from the developer via the CORBA classes provided by VisiBroker.
Our "simple" example is now complete!
| Home | Description | Example | Availability | Recommendations | References |
Feedback? Send it to Ken Anderson.
Last Modified: 12/11/97; 1:49:55 PM PST
Kenneth M. Anderson