This document is a high-level overview of how to create a complete CORBA (Common Object Request Broker Architecture) application using IDL (Interface Definiton Language) to define interfaces and the Java IDL compiler to generate stubs and skeletons. This document describes using the ImplBase Inheritance Server-Side Model.
The idlj compiler now generates server-side mappings based on the POA Inheritance Model as the default. For compatibility with existing applications, a new flag has been added to the idlj compiler to allow it to generate server-side mappings based on the ImplBase Inheritance Model, -oldImplBase.
NOTE: ImplBase is deprecated in favor of the POA model, but is provided to allow compatibility with servers written in J2SE 1.3 and prior. We do not recommend creating new servers using this nonstandard model.
This document contains:
Hello.idl
)The first step to creating a CORBA application is to specify all of your objects and their interfaces using the OMG's Interface Definition Language (IDL). IDL has a syntax similar to C++ and can be used to define modules, interfaces, data structures, and more. The IDL can be mapped to a variety of programming languages. The IDL mapping for Java is summarized in IDL to Java Language Mapping Summary.
The following code is written in the OMG IDL, and describes a CORBA object whose sayHello() operation returns a string and whose shutdown() operation shuts down the ORB. To learn more about OMG IDL Syntax and Semantics, link to the OMG Web site, and read Chapter 3 of the CORBA Specification.
Hello.idl
module HelloApp { interface Hello { string sayHello(); oneway void shutdown(); }; };NOTE: When writing code in OMG IDL, do not use an interface name as the name of a module. Doing so runs the risk of getting inconsistent results when compiling with tools from different vendors, thereby jeopardizing the code's portability. For example, code containing the same names could be compiled with the IDL to Java compiler and get one result. The same code compiled with another vendor's IDL to Java compiler could produce a different result.
To complete the application, you simply provide the server
(HelloServer.java
) and client
(HelloClient.java
) implementations.
HelloServer.java
)The example server consists of two classes, the servant and the server. The servant, HelloImpl, is the implementation of the Hello IDL interface; each Hello instance is implemented by a HelloImpl instance. The servant is a subclass of _HelloImplBase, which is generated by the idlj compiler from the example IDL. The servant contains one method for each IDL operation, in this example, the sayHello() and shutdown() methods. Servant methods are just like ordinary Java methods; the extra code to deal with the ORB, with marshaling arguments and results, and so on, is provided by the skeleton.
The HelloServer class has the server's main() method, which:
The HelloServer for the ImplBase server-side implementation differs only slightly from its POA counterpart. The sections of the POA-based server that get a reference to the root POA and activate the POAManager are not necessary for this implementation, which follows:
HelloServer.java
// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import java.util.Properties; class HelloImpl extends _HelloImplBase{ private ORB orb; public void setORB(ORB orb_val){ orb = orb_val; } public String sayHello(){ return "\nHello world !!\n"; } public void shutdown(){ orb.shutdown(false); } } 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 HelloImpl helloImpl = new HelloImpl(); helloImpl.setORB(orb); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); Hello href = HelloHelper.narrow(helloImpl); // bind the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; 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 ..."); } }
HelloClient.java
)The example application client that follows is similar to the one presented in the default tutorial, however, the new Interoperable Naming Service features are not used in this example to preserve backward compatibility. The example client application:
HelloClient.java
// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class HelloClient{ static Hello helloImpl; 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 helloImpl = HelloHelper.narrow(ncRef.resolve(path)); System.out.println("Obtained a handle on server object: " + helloImpl); System.out.println(helloImpl.sayHello()); helloImpl.shutdown(); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }
Despite its simple design, the Hello World program lets you learn and experiment with all the tasks required to develop almost any CORBA program that uses static invocation.
This example requires a naming service, which is a CORBA service that allows CORBA objects to be named by means of binding a name to an object reference. The name binding may be stored in the naming service, and a client may supply the name to obtain the desired object reference. The two options for Naming Services shipped with this version of Java SE are tnameserv, a transient naming service, and orbd (Solaris, Linux, or Mac OS X or Windows), which is a daemon process containing a Bootstrap Service, a Transient Naming Service, a Persistent Naming Service, and a Server Manager. This example uses orbd.
When running this example, remember that, when using Solaris software, you must become root to start a process on a port under 1024. For this reason, we recommend that you use a port number greater than or equal to 1024. The -ORBInitialPort option is used to override the default port number in this example. The following instructions assume you can use port 1050 for the Java IDL Object Request Broker Daemon, orbd. You can substitute a different port if necessary. When running these examples on a Windows machine, subtitute a backslash (\) in path names.
To run this client-server application on your development machine:
NOTE: ImplBase is deprecated in favor of the POA model,
but is provided to allow compatibility with servers written in J2SE
1.3 and prior. We do not recommend creating new servers using this
nonstandard model.
idlj -fall -oldImplBase Hello.idl
You must use the -fall option with the idlj compiler to generate both client and server-side bindings. This command line will generate the default server-side bindings, which assumes the POA programming model. The -oldImplBase option tells the compiler to generate the ImplBase Inheritance Model server-side bindings, instead of the default POA Inheritance Model server-side bindings. For more information on the idlj options, see the idlj man page (Solaris, Linux, or Mac OS X or Windows).
The idlj compiler generates a number of files. The actual number of files generated depends on the options selected when the IDL file is compiled. The generated files provide standard functionality, so you can ignore them until it is time to deploy and run your program. The files generated by the idlj compiler for Hello.idl, with the -fall command line option, are:
This abstract class is the server skeleton, providing basic CORBA functionality for the server. It implements the InvokeHandler and the Hello interface. It inherits from org.omg.CORBA.portable.ObjectImpl. The server class HelloImpl inherits from _HelloImplBase.
This class is the client stub, providing CORBA functionality for the client. It inherits from org.omg.CORBA.portable.ObjectImpl and implements the Hello interface.
This interface contains the Java version of our IDL interface. The Hello.java interface inherits from org.omg.CORBA.Object, providing standard CORBA object functionality. It also inherits from HelloOperations and org.omg.CORBA.portable.IDLEntity.
This class provides auxiliary functionality, notably the narrow() method required to cast CORBA object references to their proper types.The Helper class is responsible for reading and writing the data type to CORBA streams, and inserting and extracting the data type from Anys. The Holder class delegates to the methods in the Helper class for reading and writing.
This final class holds a public instance member of type Hello. Whenever the IDL type is an out or an inout parameter, the Holder class is used. It provides operations for org.omg.CORBA.portable.OutputStream and org.omg.CORBA.portable.InputStream arguments, which CORBA allows, but which do not map easily to Java's semantics. The Holder class delegates to the methods in the Helper class for reading and writing. It implements org.omg.CORBA.portable.Streamable.
This interface contains the methods sayHello() and shutdown(). The IDL-to-Java mapping puts all of the operations defined on the IDL interface into this file, which is shared by both the stubs and skeletons.
javac *.java HelloApp/*.java
To start orbd from a command shell on Solaris, Linux, or Mac OS X, enter:
orbd -ORBInitialPort 1050 -ORBInitialHost localhost&
From an MS-DOS system prompt (Windows), enter:
start orbd -ORBInitialPort 1050 -ORBInitialHost localhost
Note that 1050 is the port on which you want the name server to run. -ORBInitialPort is a required command-line argument. Note that when using Solaris software, you must become root to start a process on a port under 1024. For this reason, we recommend that you use a port number greater than or equal to 1024.
-ORBInitialHost is an optional command-line argument. For this example, since both client and server on running on the development machine, we have set the host to localhost. When developing on more than one machine, you will replace this with the name of the host. For an example of how to run this program on two machines, see Running the Hello World Program on 2 machines.
To start the Hello server from a command shell on Solaris, Linux, or Mac OS X, enter:
java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost&
From an MS-DOS system prompt (Windows), enter:
start java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost
For this example, you can omit -ORBInitialHost localhost since the name server is running on the same host as the Hello server. If the name server is running on a different host, use -ORBInitialHost nameserverhost to specify the host on which the IDL name server is running.
Specify the name server (orbd) port as done in the previous step, for example, -ORBInitialPort 1050.
When the server is running, it will echo the following message back to the terminal:
HelloServer ready and waiting ...
java HelloClient -ORBInitialPort 1050 -ORBInitialHost localhost
For this example, you can omit -ORBInitialHost localhost since the name server is running on the same host as the Hello client. If the name server is running on a different host, use -ORBInitialHost nameserverhost to specify the host on which the IDL name server is running.
Specify the name server (orbd) port as done in the previous step, for example, -ORBInitialPort 1050.
When the client is running, the following message will echo to the terminal:
Obtained a handle on server object: IOR: ... Hello World !! HelloServer Exiting ...
When you have finished this tutorial, be sure to shut down or kill the name server (orbd). To do this from a DOS prompt, select the window that is running the server and enter Ctrl+C to shut it down. To do this from a shell on Solaris, Linux, or Mac OS X, find the process, and kill it. The server will continue to wait for invocations until it is explicitly stopped.
Running the Hello World Application on Two Machines describes one way of distributing the simple application across two machines - a client and a server.