COM 3240
Prof. Lorenz
Out: May 9, 2001
Due: May 16, 2001
This document: CorbaTutorial.doc
Tutorial
#1: CORBA Basics – Hello World
Readings
Goal
You are given
You are required
Instructions
idltojava -fno-cpp
hello.idl
You’ll see now that a subfolder
named HelloApp was created and contains some java file. We’ll cover some of
them later.
will get a compiler warning about
deprecated methods in the generated code.
Ignore this.
javac -classpath .
HelloApp/*.java
You’ll see now that the subfolder HelloApp contains class files for each one of the java files generated by the IDL compiler.
javac -classpath . *.java
You now have the client and server
classes for the client server program.
Note that beside the HelloClient.class and HelloServer.class, another
class named HelloServant.class was generated. This class
is defined in the HelloServer.java file and will be discussed later.
In Windows:
start tnameserv
–ORBInitialPort 3240
In Unix:
tnameserv –ORBInitialPort
3240 &
Note that the –ORBInitialPort
indicates the port which the Name Service is listening to.
In Windows:
start java -cp .
HelloServer -ORBInitialPort 3240
In UNIX:
java -cp . HelloServer
-ORBInitialPort 3240 &
Note: if your name service is
running on a different machine then the Server program, you should also add the
–ORBInitialHost hostname option in the command
line.
For example, if you started the
name service on the denali machine and your server program is
running on your local machine then the command line should be:
java -cp . HelloServer -ORBInitialPort 3240
–ORBInitialHost denali &
java -cp . HelloClient
-ORBInitialPort 3240
Note: if your name service is
running on a different machine then the Client program, you should also add the
–ORBInitialHost hostname option in the command
line. See example in previous step.
Description for the CORBA
tutorial
module HelloApp
{
interface Hello
{
string sayHello();
};
};
Speaking of java terms, the module HelloApp will be the name of the generated package name HelloApp.
The
interface Hello represents a Java interface with
the same name.
The interface contains a single
method named sayHello(). The return value of the method
is string. Note that in IDL string is written with small letter. In the end of
this document you’ll find a table that converts common java types to IDL types.
2. After you run step two in the instructions you’ll see that some java files were generated in the HelloApp subfolder. Lets look at some of these files more closely.
a. Hello.java:
package
HelloApp;
public
interface Hello
extends
org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {
String sayHello();
}
You can see that this is a regular Java interface that defines one method sayHello() with a return value of type String.
Remote objects that run on server programs implement this interface.
This interface is the only thing that the client needs to know about the remote objects. The implementation is not important because it’s running on the server process. The client only needs to create a handle to such remote object and then just invoke a method defined by the interface.
b. _HelloImplBase.java
package
HelloApp;
public
abstract class _HelloImplBase extends org.omg.CORBA.DynamicImplementation
implements HelloApp.Hello {
// Constructor
public _HelloImplBase() {
super();
}
…
}
This class is a basic implementation for the Hello interface. The implementation contains some CORBA generated code. In order to create classes of type Hello this class should be inherited and implement the Hello interface. (see HelloServant class below).
c. HelloHelper.java
package
HelloApp;
public
class HelloHelper {
…
public
static HelloApp.Hello narrow(org.omg.CORBA.Object that) {
…
}
…
}
The HelloHelper class is a utility class generated for the client in order to create the handle for the remote object of type Hello. The only method that is worth looking at is narrow which gets as a parameter some kind of a CORBA object and returns a handle to an object of type Hello. This object is actually a _HelloStub object but the client doesn’t care about that. All the client cares is that he can invoke methods on the handle according to the Hello interface.
3. Lets look now at the client program in HelloClient.java:
public
class HelloClient
{
public static void main(String args[])
{
1. try{
// create and initialize the ORB
2. ORB orb = ORB.init(args, null);
// get the root naming context
3. org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
4. NamingContext ncRef =
NamingContextHelper.narrow(objRef);
// resolve the Object Reference in
Naming
5. NameComponent nc = new
NameComponent("My Hello", "");
6. NameComponent path[] = {nc};
7. Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
// call the Hello server object
and print results
8. String hello = helloRef.sayHello();
9. System.out.println(hello);
10. } catch (Exception e) {
11. System.out.println("ERROR : " + e) ;
12. e.printStackTrace(System.out);
}
}
}
As you can see, the first 6 lines of code are standard to any CORBA client program. The idea is to connect to a Name Service and retrieve an object that was registered with a specific name by another process. In our case, we are retrieving an Object named “My Hello” (line 5) which is registered by the server program and then, using the helper, we create a stub (handle) of type Hello for that Object (line 7).
Then we can invoke any method from the Hello interface on the handle we got as if the object was local (line 8).
4. Now lets look at the server program in HelloServer.java
a. The first thing we see is a HelloServant class:
class
HelloServant extends _HelloImplBase
{
public String sayHello()
{
return "\nHello world !!\n";
}
}
This is the actual remote class (to create remote objects), which implements the interface we defined in the Hello.idl file. You can see that this class extends from _HelloImplBase and if you go inside the code of _HelloImplBase you can see that it implements the Hello interface produced by the IDL compiler.
b. The server program:
public
class HelloServer {
public static void main(String args[])
{
try{
// create and initialize the ORB
1. ORB orb = ORB.init(args, null);
// create servant and register it
with the ORB
2. HelloServant helloRef = new
HelloServant();
3. orb.connect(helloRef);
// get the root naming context
4. String[] services =
orb.list_initial_services();
5. int j = 0;
6. for (j=0;j<services.length;j++)
{
7.
System.out.println(services[j]);
8. }
9. org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
10. NamingContext ncRef =
NamingContextHelper.narrow(objRef);
// bind the Object Reference in
Naming
11. NameComponent nc = new
NameComponent("My Hello", "");
12. NameComponent path[] = {nc};
13. ncRef.rebind(path, helloRef);
// wait for invocations from
clients
14. java.lang.Object sync = new
java.lang.Object();
15. synchronized (sync) {
16. sync.wait();
17. }
18. } catch (Exception e) {
19. System.err.println("ERROR:
" + e);
20. e.printStackTrace(System.out);
}
}
}
As we’ve seen in the client program the server also contains some standard CORBA code for registering objects in the Naming Service.
First the program creates an Object of type HelloServant (which is also of type Hello) and then connects its reference to the ORB (lines 2,3).
The actual registering of the reference to the Naming service is done in lines 11 to 13.
Appendix – IDL to Java type
conversion
boolean
boolean
char
char CORBA::DATA_CONVERSION
wchar
char CORBA::DATA_CONVERSION
octet
byte
string
java.lang.String CORBA::MARSHAL
CORBA::DATA_CONVERSION
wstring java.lang.String CORBA::MARSHAL
CORBA::DATA_CONVERSION
short short
unsigned
short short
long int
unsigned
long int
long long long
unsigned
long long
long
long
float float
double double
fixed java.math.BigDecimal CORBA::DATA_CONVERSION