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

 

  1. Before you start you need to make sure you have the following:
    1. JDK1.2.2 (or a newer version) installed on you machine
    2. The IDL to Java compiler. For Windows, download the idltojava.exe and put it in your bin directory of the JDK (i.e. c:\JDK1.2.2\bin). If you’re using the ccs Unix machine you can run it from /course/com3240/TA/corba/idlcompiler/idltojava or download idltojava (unix)

 

  1. Extract the zip file to your local directory and run the IDL compiler on the Hello.idl file:

 

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.

 

  1. Compile the generated Java files found in the subdirectory HelloApp.  Note that you

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.

 

 

 

 

  1. Compile the client and server code

 

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.

 

  1. Start CORBA Name Service in the background.  This prints out some information about the running ORB and the port on which it is running.

 

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.

 

  1. Start the server in the background.  This prints out "Name Service"

 

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 &

 

 

  1. Start the client.  This prints out Hello world !!

 

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

 

  1. First lets look at the Hello.idl file:

 

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

 

IDL Type             Java type                 Exceptions

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