# Example 3: Hello World with Callback Object

Client programs often react to changes or updates that occur in a server. For example, a client graph or spreadsheet program might need to be updated with each stock price update on a stock market server. The client has two options in this scenario: (1) periodically ask for the stock price via a method request on the stock server or (2) ask to be notified by the server whenever a price change occurs. The second option is referred to as a "callback".

Example 3 illustrates how a client program can pass a callback object to a server. The server then issues a method request on the callback object and thereby notifies the client.

Example 3 is identical to Example 1 except for the callback enhancements. This page only discusses the code necessary to these enhancements.

This page contains:

- The IDL for a "Hello world" program with a callback.
- A server implementation that callsback to a client.
- A client that sends a callback object reference to a server.

Instructions for compiling and running the example are provided.

## Interface Definition (`Hello.idl`)

    module HelloApp
    {
        interface HelloCallback
        {
            void callback(in string message);
        };

        interface Hello
        {
            string sayHello(in HelloCallback objRef, in string message);
        };
    };

A `HelloCallback` is defined, which the client will implement.
The `sayHello` method is modified to take an object reference argument and string argument. The object reference argument provides a means for the client to pass a callback object to the server, which the server can invoke. The string argument is the string that the server will send back to the client.

## Implementing the Server (`HelloServer.java`)

    // Copyright and License

    import HelloApp.*;
    import org.omg.CosNaming.*;
    import org.omg.CosNaming.NamingContextPackage.*;
    import org.omg.CORBA.*;

    class HelloServant extends _HelloImplBase
    {
        public String sayHello(HelloCallback callobj, String msg)
        {
    	callobj.callback(msg);
    	return "\nHello world !!\n";
        }
    }

    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 (Exception e) {
    	    System.err.println("ERROR: " + e);
    	    e.printStackTrace(System.out);
    	}
        }
    }

The `sayHello` method implementation has been modified to invoke the callback object that it receives.

## Implementing the Client (`HelloClient.java`)

    // Copyright and License

    import HelloApp.*;
    import org.omg.CosNaming.*;
    import org.omg.CORBA.*;

    class HelloCallbackServant extends _HelloCallbackImplBase
    {
        public void callback(String notification)
        {
            System.out.println(notification);
        }
    }

    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));

    	    HelloCallbackServant helloCallbackRef = new HelloCallbackServant();
                orb.connect(helloCallbackRef);

    	    // call the Hello server object and print results
    	    String hello = helloRef.sayHello(helloCallbackRef,"\ntest..\n");
    	    System.out.println(hello);

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

The client implements the `HelloCallbackServant` object.
The `HelloClient.main` instantiates the callback object and passes it to the server. The client must also register the callback object with the ORB.

## Building and Running Hello World

The following instructions assume you can use port 1050 for the Java IDL name server. Substitute a different port if necessary. Note that for ports below 1024, you need root access on UNIX machines, and administrator privileges on Windows95 and NT. Note also that the instructions use a slash (/) for path names. Windows95 and NT users should subtitute a backslash (\).

- Create the source code files as shown above.
- Run `idlj` on the IDL file to create stubs and skeletons:

      	idlj -fall Hello.idl

- Compile the `.java` files, including the stubs and skeletons:

      	javac *.java HelloApp/*.java

- Make sure the name server is running:

      	tnameserv -ORBInitialPort 1050&

- Start the Hello server:

      	java HelloServer -ORBInitialPort 1050

- Run the Hello application client from a different shell than the server:

      	java HelloClient -ORBInitialPort 1050

Home

Copyright © 1995-98 Sun Microsystems, Inc. All Rights Reserved.