Professional Documents
Culture Documents
Java TM IDL is a technology for distributed objects--that is, objects interacting on different
platforms across a network. Java IDL is similar to RMI (Remote Method Invocation), which
supports distributed objects written entirely in the Java programming language. However, Java
IDL enables objects to interact regardless of whether they're written in the Java programming
language or another language such as C, C++, COBOL, or others.
This is possible because Java IDL is based on the Common Object Request Brokerage Architecture
(CORBA), an industry-standard distributed object model. A key feature of CORBA is IDL, a
language-neutral Interface Definition Language. Each language that supports CORBA has its own
IDL mapping--and as its name implies, Java IDL supports the mapping for Java.
To support interaction between objects in separate programs, Java IDL provides an Object Request
Broker, or ORB. The ORB is a class library that enables low-level communication between Java
IDL applications and other CORBA-compliant applications.
This tutorial teaches the basic tasks in building a CORBA distributed application using Java IDL.
You will build the classic "Hello World" program as a distributed application, with both applet and
application clients. The Hello World program has a single operation that returns a string to be
printed.
Any relationship between distributed objects has two sides: the client and the server. The server
provides a remote interface, and the client calls a remote interface. These relationships are
common to most distributed object standards, including RMI and CORBA. Note that in this
context, the terms client and server define object-level rather than application-level interaction--
any application could be a server for some objects and a client of others. In fact, a single object
could be the client of an interface provided by a remote object and at the same time implement an
interface to be called remotely by other objects.
This figure shows how a one-method distributed object is shared between a CORBA client and
server to implement the classic "Hello World" application.
On the client side, the application includes a reference for the remote object. The object reference
has a stub method, which is a stand-in for the method being called remotely. The stub is actually
wired into the ORB, so that calling it invokes the ORB's connection capabilities, which forwards
the invocation to the server.
On the server side, the ORB uses skeleton code to translate the remote invocation into a method
call on the local object. The skeleton translates the call and any parameters to their
implementation-specific format and calls the method being invoked. When the method returns, the
skeleton code transforms results or errors, and sends them back to the client via the ORBs.
Between the ORBs, communication proceeds by means of a shared protocol, IIOP--the Internet
Inter-ORB Protocol. IIOP, which is based on the standard TCP/IP internet protocol, defines how
-1-
Java IDL Tutorial and Guide
CORBA-compliant ORBs pass information back and forth. Like CORBA and IDL, the IIOP
standard is defined by OMG, the Object Management Group.
The Java IDL Development Process and the Hello World Tutorial
This tutorial teaches the basic tasks in building a CORBA distributed application using Java IDL.
You will build the classic Hello World program as a distributed application, with both applet and
application clients. The Hello World program has a single operation that returns a string to be
printed.
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. The following
steps provide a general guide to designing and developing a distributed object application with
Java IDL. Links to the relevant steps of the tutorial will guide you through creating this sample
application.
You define the interface for the remote object using the OMG's interface definition
langauge. You use IDL instead of the Java language because the idlj compiler
automatically maps from IDL, generating all Java language stub and skeleton source files,
along with the infrastructure code for connecting to the ORB. Also, by using IDL, you make
it possible for developers to implement clients and servers in any other CORBA-compliant
language.
Note that if you're implementing a client for an existing CORBA service, or a server for an
existing client, you would get the IDL interfaces from the implementer--such as a service
provider or vendor. You would then run the idlj compiler over those interfaces and follow
these steps.
Writing the IDL file in this tutorial walks you through these steps for the simple "Hello
World" example.
When you run the idlj compiler over your interface definition file, it generates the Java
version of the interface, as well as the class code files for the stubs and skeletons that
enable your applications to hook into the ORB.
Mapping Hello.idl to Java in this tutorial walks you through these steps for the simple
"Hello World" example.
Once you run the idlj compiler, you can use the skeletons it generates to put together your
server application. In addition to implementing the methods of the remote interface, your
server code includes a mechanism to start the ORB and wait for invocation from a remote
client.
Developing the Hello World Server walks you through writing a simple server for the
"Hello World" application.
Similarly, you use the stubs generated by the idlj compiler as the basis of your client
application. The client code builds on the stubs to start its ORB, look up the server using
-2-
Java IDL Tutorial and Guide
the name service provided with Java IDL, obtain a reference for the remote object, and call
its method.
Developing a Client Application walks you through writing a simple client application
and Developing a Client Applet walks you through writing a client applet that performs
the same functions as the client application.
Once you implement a server and a client, you can start the name service, then start the
server, then run the client.
Compiling and Running the Hello World Application walks you through compiling
and running the server and client program that together make up the "Hello World"
application.
Using Stringified Object References walks you through making an object reference when there
is no naming service.
Running the Hello World Application on 2 Machines describes one way of distributing the
simple application across two machines - a client and a server.
Although concepts are explained as they are introduced in the tutorial, you will find more
information in the Concepts section. New terms are linked to their definitions throughout the
tutorial.
The Object Management Group no longer maintains this site, but the CORBA for Beginnners page
contains links to web pages that provide introductory CORBA information.
Note: All command and troubleshooting instructions apply to Java 2 SDK v1.3.0 and its version of
idlj only.
Before you start working with Java IDL, you need to install version 1.3 of the Java 2 SDK. J2SDK
v1.3.0 provides the Application Programming Interface (API) and Object Request Broker (ORB)
needed to enable CORBA-based distributed object interaction, as well as the idlj compiler. The idlj
compiler uses the IDL-to-Java mapping to convert IDL interface definitions to corresponding Java
interfaces, classes, and methods, which you can then use to implement your client and server code.
This section teaches you how to write a simple IDL interface definition and how to translate the
IDL interface to Java. It also describes the purpose of each file generated by the idlj compiler.
1. Writing Hello.idl
2. Understanding the IDL file
3. Mapping Hello.idl to Java
4. Understanding the idlj Compiler Output
-3-
Java IDL Tutorial and Guide
Writing Hello.idl
module HelloApp
{
interface Hello
{
string sayHello();
};
};
The IDL for Hello World is extremely simple; its single interface has a single operation. You need
perform only three steps:
A CORBA module is a namespace that acts as a container for related interfaces and declarations.
It corresponds closely to a Java package. Each module statement in an IDL file is mapped to a
Java package statement.
module HelloApp
{
// Subsequent lines of code here.
};
When you compile the IDL, the module statement will generate a package statement in the Java
code.
Like Java interfaces, CORBA interfaces declare the API contract an object has with other objects.
Each interface statement in the IDL maps to a Java interface statement when mapped.
-4-
Java IDL Tutorial and Guide
module HelloApp
{
interface Hello // These
{ // are the
// interface
}; // statement.
};
When you compile the IDL, this statement will generate an interface statement in the Java code.
Your client and server classes will implement the Hello interface in different ways.
CORBA operations are the behavior that servers promise to perform on behalf of clients that
invoke them. Each operation statement in the IDL generates a corresponding method statement in
the generated Java interface.
module HelloApp
{
interface Hello
{
string sayHello(); // This line is the operation statement.
};
};
Our little Hello World application has only a single operation, so Hello.idl is now complete.
The tool idlj reads OMG IDL files and creates the required Java files. The idlj compiler defaults to
generating only the client-side bindings. If you need both client-side bindings and server-side
skeletons (as you do for our Hello World program), you must use the -fall option when running the
idlj compiler. For more information on the IDL-to-Java compiler options, follow the link.
If you list the contents of the directory, you will see that a directory called HelloApp has been
created and that it contains six files. Open Hello.java in your text editor. Hello.java is the
signature interface and is used as the signature type in method declarations when interfaces of the
specified type are used in other interfaces. It looks like this:
package HelloApp;
/**
* HelloApp/Hello.java
* Generated by the IDL-to-Java compiler (portable), version "3.0"
* from Hello.idl
*/
-5-
Java IDL Tutorial and Guide
With an interface this simple, it is easy to see how the IDL statements map to the generated Java
statements.
The single surprising item is the extends statement. All CORBA objects are derived from
org.omg.CORBA.Object to ensure required CORBA functionality. The required code is generated
by idlj; you do not need to do any mapping yourself.
In previous versions of the idlj compiler (known as idltojava), the operations defined on the IDL
interface would exist in this file as well. Starting with J2SDK v1.3.0, the IDL-to-Java mapping
puts all of the operations defined on the IDL interface in the operations interface,
HelloOperations.java. The operations interface is used in the server-side mapping and as a
mechanism for providing optimized calls for co-located clients and servers. For Hello.idl, this file
looks like this:
package HelloApp;
/**
* HelloApp/HelloOperations.java
* Generated by the IDL-to-Java compiler (portable), version "3.0"
* from Hello.idl
*/
Because there is only one operation defined in this interface, it is easy to see how the IDL
statements map to the generated Java statements.
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:
_HelloImplBase.java
-6-
Java IDL Tutorial and Guide
This abstract class is the server skeleton, providing basic CORBA functionality for the
server. It implements the Hello.java interface. The server class HelloServant extends
_HelloImplBase.
_HelloStub.java
This class is the client stub, providing CORBA functionality for the client. It implements
the Hello.java interface.
Hello.java
This signature interface contains the Java version of our IDL interface. The Hello.java
interface extends org.omg.CORBA.Object, providing standard CORBA object functionality.
It also extends IDLEntity, and is used as the signature type in method declarations when
interfaces of the specified type are used in other interfaces.
HelloHelper.java
This final class provides auxiliary functionality, notably the narrow() method required to
cast CORBA object references to their proper types.
HelloHolder.java
This final class holds a public instance member of type Hello. It provides operations for
out and inout arguments, which CORBA allows, but which do not map easily to Java's
semantics.
HelloOperations.java
This operations interface contains the single method sayHello(). The IDL-to-Java
mapping puts all of the operations defined on the IDL interface into this file. The
operations interface is used in the server-side mapping and as a mechanism for providing
optimized calls for co-located clients and servers.
When you write the IDL interface, you do all the programming required to generate all these files
for your distributed application. The next steps are to implement the client and server classes. In
the steps that follow, you will create HelloClient.java and HelloApplet.java client classes and the
HelloServer.java class.
Troubleshooting
If you try to run idlj on the file Hello.idl and the system cannot find idlj, it is most likely not
in your path. Make certain that the location of idlj (the J2SDK v.1.3 .bin directory) is in
your path, and try again.
Provides the basics on mapping IDL constructs to the corresponding Java statements.
Provides the complete specification for OMG Interface Definition Language. At this writing,
the specification can be downloaded from
http://www.omg.org/technology/documents/new_formal/corba.htm.
The example server consists of two classes, the servant and the server. The servant, HelloServant,
is the implementation of the Hello IDL interface; each Hello instance is implemented by a
HelloServant 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, just the sayHello() method. Servant methods are just like ordinary Java methods; the
-7-
Java IDL Tutorial and Guide
extra code to deal with the ORB, with marshaling arguments and results, and so on, is provided by
the server and the stubs.
This lesson introduces the basics of writing a CORBA transient server. The steps in this topic
cover:
1. Creating HelloServer.java
2. Understanding HelloServer.java
3. Compiling the Hello World Server
Creating HelloServer.java
To create HelloServer.java,
1. Start your text editor and create a file named HelloServer.java in your main project
directory, Hello.
2. Enter the following code for HelloServer.java in the text file. The following section,
Understanding HelloServer.java, explains each line of code in some detail.
-8-
Java IDL Tutorial and Guide
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
} catch(Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
}
}
Understanding HelloServer.java
This section explains each line of HelloServer.java, describing what the code does, as well as why it
is needed for this application.
The structure of a CORBA server program is the same as most Java applications: You import
required library packages, declare the server class, define a main() method, and handle exceptions.
-9-
Java IDL Tutorial and Guide
Every Java application needs a main method. It is declared within the scope of the HelloServer
class:
Because all CORBA programs can throw CORBA system exceptions at runtime, all of the main()
functionality is placed within a try-catch block. CORBA programs throw runtime exceptions
whenever trouble occurs during any of the processes (marshaling, unmarshaling, upcall) involved
in invocation. The exception handler simply prints the exception and its stack trace to standard
output so you can see what kind of thing has gone wrong.
try{
} catch(Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
Just like in the client application, a CORBA server also needs a local ORB object. Every server
instantiates an ORB and registers its servant objects so that the ORB can find the server when it
receives an invocation for it.
The ORB variable is declared and initialized inside the try-catch block.
The call to the ORB's init() method passes in the server's command line arguments, allowing you to
set certain properties at runtime.
A server is a process that instantiates one or more servant objects. The servant implements the
interface generated by idlj and actually performs the work of the operations on that interface.
Our HelloServer needs a HelloServant.
-10-
Java IDL Tutorial and Guide
We instantiate the servant object inside the try-catch block, just below the call to init(), as shown:
The section of code describing the servant class will be explained in a later step.
The next step is to connect the servant to the ORB, so that the ORB can recognize invocations on it
and pass them along to the correct servant:
orb.connect(helloRef);
At the end of HelloServer.java, outside the HelloServer class, we define the class for the servant
object.
The servant is a subclass of _HelloImplBase so that it inherits the general CORBA functionality
generated for it by the compiler.
The HelloServer works with the naming service to make the servant object's operations available
to clients. The server needs an object reference to the name service, so that it can register itself
and ensure that invocations on the Hello interface are routed to its servant object.
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
The string "NameService" is defined for all CORBA ORBs. When you pass in that string, the ORB
returns a naming context object that is an object reference for the name service.
-11-
Java IDL Tutorial and Guide
As with all CORBA object references, objRef is a generic CORBA object. To use it as a
NamingContext object, you must narrow it to its proper type. The call to narrow() is just below the
previous statement:
Here you see the use of an idlj-generated helper class, similar in function to HelloHelper. The
ncRef object is now an org.omg.CosNaming.NamingContext and you can use it to access the
naming service and register the server, as shown in the next topic.
This statement sets the id field of nc to "Hello" and the kind component to the empty string. Make
sure there are no spaces between the "".
Because the path to the Hello has a single element, we create the single-element array that
NamingContext.resolve requires for its work:
Finally, we pass path and the servant object to the naming service, binding the servant object to
the "Hello" id:
ncRef.rebind(path, helloRef);
Now, when the client calls resolve("Hello") on the initial naming context, the naming service
returns an object reference to the Hello servant.
The previous sections describe the code that makes the server ready; the next section explains the
code that enables it to simply wait around for a client to request its service. The following code,
which is at the end of (but within) the try-catch block, shows how to accomplish this.
This form of Object.wait() requires HelloServer to remain alive (though quiescent) until an
invocation comes from the ORB. Because of its placement in main(), after an invocation completes
and sayHello() returns, the server will wait again.
Now we will compile the HelloServer.java so that we can correct any error before continuing with
this tutorial.
Windows users note that you should substitute backslashes (\) for the slashes (/) in all paths in
this document.
-12-
Java IDL Tutorial and Guide
To compile HelloServer.java:
3. Correct any errors in your file and recompile if necessary. (You can copy the file from
HelloServer.java, if you have trouble finding your typographical errors).
4. The files HelloServer.class and HelloServant.class are generated in the Hello
directory.
This topic introduces the basics of writing a CORBA client application. To create a CORBA client
applet, follow the link. Included in this lesson are:
1. Creating HelloClient.java
2. Understanding HelloClient.java
3. Compiling HelloClient.java
Creating HelloClient.java
To create HelloClient.java,
1. Start your text editor and create a file named HelloClient.java in your main project
directory, Hello.
2. Enter the following code for HelloClient.java in the text file. The following section,
Understanding HelloClient.java, explains each line of code in some detail.
-13-
Java IDL Tutorial and Guide
try{
} catch(Exception e) {
System.out.println("ERROR : " + e);
e.printStackTrace(System.out);
}
}
}
Understanding HelloClient.java
This section explains each line of HelloClient.java, describing what the code does, as well as
why it is needed for this application.
The basic shell of a CORBA client is the same as many Java applications: You import required
library packages, declare the application class, define a main method, and handle exceptions.
-14-
Java IDL Tutorial and Guide
Every Java application needs a main() method. It is declared within the scope of the HelloClient
class, as follows:
Because all CORBA programs can throw CORBA system exceptions at runtime, all of the main()
functionality is placed within a try-catch block. CORBA programs throw system exceptions
whenever trouble occurs during any of the processes (marshaling, unmarshaling, upcall) involved
in invocation.
Our exception handler simply prints the name of the exception and its stack trace to standard
output so you can see what kind of thing has gone wrong.
try{
} catch(Exception e) {
System.out.println("ERROR : " + e);
e.printStackTrace(System.out);
}
A CORBA client needs a local ORB object to perform all of its marshaling and IIOP work. Every
client instantiates an org.omg.CORBA.ORB object and initializes it by passing to the object certain
information about itself.
The ORB variable is declared and initialized inside the try-catch block.
The call to the ORB's init() method passes in your application's command line arguments,
allowing you to set certain properties at runtime.
Now that the application has an ORB, it can ask the ORB to locate the actual service it needs, in
this case the Hello server. There are a number of ways for a CORBA client to get an initial object
reference; our client application will use the COS Naming Service specified by OMG and provided
with Java IDL. See Using Stringified Object References for information on how to get an initial
object reference when there is no naming service available.
-15-
Java IDL Tutorial and Guide
The first step in using the naming service is to get the initial naming context. In the try-catch
block, below your ORB initialization, you call orb.resolve_initial_references() to get an
object reference to the name server:
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
The string "NameService" is defined for all CORBA ORBs. When you pass in that string, the ORB
returns the initial naming context, an object reference to the name service.
As with all CORBA object references, objRef is a generic CORBA object. To use it as a
NamingContext object, you must narrow it to its proper type.
Here we see the use of an idlj-generated helper class, similar in function to HelloHelper. The
ncRef object is now an org.omg.CosNaming.NamingContext and you can use it to access the
naming service and find other services. You will do that in the next step.
Names can have different structures depending upon the implementation of the naming service.
Consequently, CORBA name servers handle complex names by way of NameComponent objects.
Each NameComponent holds a single part, or element, of the name. An array of NameComponent
objects can hold a fully specified path to an object on any computer file or disk system.
To find the Hello server, you first need a NameComponent to hold an identifying string for the Hello
server.
This statement sets the id field of nc to "Hello" and the kind field to an empty string. Be sure this
is an empty string, do not enter a space between "".
Because the path to the Hello object has just one element, we have created a single-element array
out of nc. The NamingContext.resolve() method requires this array for its work:
Finally, we pass path to the naming service's resolve() method to get an object reference to the
Hello server and narrow it to a Hello object:
Here you see the HelloHelper helper class at work. The resolve() method returns a generic
CORBA object as you saw above when locating the name service itself. Therefore, you immediately
narrow it to a Hello object, which is the object reference you need to perform the rest of your work.
-16-
Java IDL Tutorial and Guide
CORBA invocations look like a method call on a local object. The complications of marshaling
parameters to the wire, routing them to the server-side ORB, unmarshaling, and placing the upcall
to the server method are completely transparent to the client programmer. Because so much is
done for you by generated code, invocation is really the easiest part of CORBA programming.
System.out.println(Hello);
Compiling HelloClient.java
Now we will compile HelloClient.java so that we can correct any errors before continuing with
this tutorial.
Windows users note that you should substitute backslashes (\) for the slashes (/) in all paths in
this document.
To compile HelloClient.java,
3. Correct any errors in your file and recompile if necessary. (You can copy the file from
HelloClient.java if you have trouble finding your typographical errors).
4. The HelloClient.class is generated to the Hello directory.
We need to create and compile the Hello server before we can successfully run the Hello client
application. Running the Hello World application is covered in Running the Hello World
Application.
Developing Clients
Covers topics of interest to CORBA client programmers
Exceptions: System Exceptions
Explains how CORBA system exceptions work and provides details on the minor codes of
Java IDL's system exceptions
Initialization: System Properties
Explains what properties can be passed to the ORB at initialization
Naming Service
Covers the COS Naming Service in greater detail
This topic introduces the basics of writing a CORBA client applet. An applet is a Java program to
be included in HTML pages and executed in Java-enabled browsers. Developing a CORBA client
applet is very similar to developing a CORBA client application, except that in the applet the code
-17-
Java IDL Tutorial and Guide
appears in the init() method rather than in the main() method. You can run the applet from the
Applet Viewer or from a Web browser that is compatible with J2SE v1.3. The steps in this lesson
are:
To create HelloApplet.java,
1. Create a file named HelloApplet.java in the main project directory, Hello, using your
favorite text editor.
2. Enter the following code for HelloApplet.java in the text file. The following section,
Understanding the Applet, explains each line of code in some detail.
} catch(Exception e) {
-18-
Java IDL Tutorial and Guide
This section explains each line of HelloApplet.java, describing what the code does, as well as
why it is needed for this applet.
The basic shell of a CORBA client applet is the same as most applets: You import required library
packages, declare the applet class, define an init() method, and handle exceptions.
The first step to creating the basic shell of the applet is to import the packages required for the
client class:
Every Java application needs a main method of some type. In an applet, the init method is used
instead of the main method. The code you write under the init method overrides the Applet's
-19-
Java IDL Tutorial and Guide
default method so that it can respond to major events. In this case, the code will describe how the
applet should be initialized each time it is loaded or reloaded. Typically, an applet will also include
start, stop, and destroy methods.
Because all CORBA programs can throw CORBA system exceptions at runtime, all of the init()
functionality is placed within a try-catch block. CORBA programs throw system exceptions
whenever trouble occurs during any of the processes (marshaling, unmarshaling, upcall) involved
in invocation.
The exception handler prints the name of the exception and its stack trace to standard output (the
Java console) so you can see what has gone wrong.
try{
} catch(Exception e) {
System.out.println("HelloApplet exception: " + e);
e.printStackTrace(System.out);
}
A CORBA client needs a local ORB object to perform all of its marshaling and IIOP work. Every
client instantiates an org.omg.CORBA.ORB object and initializes it by passing certain information
about itself to the ORB.
You declare and initialize an ORB variable inside the try-catch block:
The call to the ORB's init() method passes in the applet, allowing you to set certain properties at
runtime. Here we have set the ORBInitialPort property to 1050 so that it connects properly to the
HelloServer.
Now that the applet has an ORB, it can ask the ORB to locate the actual service it needs, in this
case the Hello server. There are a number of ways for a CORBA client to get an initial object
reference; your client applet will use the COS Naming Service specified by OMG and provided with
Java IDL.
-20-
Java IDL Tutorial and Guide
The first step in using the naming service is to get the initial naming context. In the try-catch
block, below your ORB initialization, you call orb.resolve_initial_references() to get an
object reference to the name service:
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
The string "NameService" is defined for all CORBA ORBs. When you pass in that string, the ORB
returns a naming context object that is an object reference to the name service.
As with all CORBA object references, objRef is a generic CORBA object. To use it as a
NamingContext object, you must narrow it to its proper type. The call to narrow() is added just
below the previous statement.
Here you see the use of an idlj-generated helper class, similar in function to HelloHelper. The
ncRef object is now an org.omg.CosNaming.NamingContext, and you can use it to access the
naming service and find other services.
Names can have different structures depending upon the implementation of the naming service.
Consequently, CORBA name servers handle complex names by way of NameComponent objects.
Each NameComponent holds a single part, or element, of the object's full name. An array of
NameComponent objects can hold a fully-qualified path to an object on any computer file or disk
system.
To find the Hello server, you first need a NameComponent to hold an identifying string for it. This
code is found directly below the call to narrow().
This statement sets the id field of nc to "Hello" and the kind field to the empty string. To make
sure it's an empty string, make sure there are no spaces between the quotation marks.
Because the path to the Hello object has just one element, create a single-element array out of nc.
The NamingContext.resolve() method requires this array for its work:
The NameComponent array is passed to the naming service's resolve() method to get an object
reference to the Hello server and narrow it to a Hello object:
Here you see the HelloHelper class at work. The resolve() method returns a generic CORBA
object as you saw above when locating the name service itself. Therefore, you immediately narrow
it to a Hello object, which is the object reference you need to perform the rest of your work.
-21-
Java IDL Tutorial and Guide
CORBA invocations look like a method call on a local object. The complications of marshaling
parameters to the wire, routing them to the server-side ORB, unmarshaling, and placing the upcall
to the server method are completely transparent to the client programmer. Because so much is
done for you by the generated code, invocation is really the easiest part of CORBA programming.
message = helloRef.sayHello();
Finally, print the results of the invocation. This code is placed outside your init() method, but
within the HelloApplet class:
To run the Hello World applet, you first need to compile the applet file and generate the Applet
subclass, then call the subclass within an HTML file using an <APPLET> tag.
1. Open a DOS prompt or terminal window. Change to the directory where the
HelloApplet.java file resides.
2. Run the Java compiler on HelloApplet.java:
3. javac HelloApplet.java
4. Correct any errors in your file and recompile if necessary. (You can copy the file from
HelloApplet.java if you have trouble finding your typographical errors).
Once you've written an applet, you need to add it to an HTML page so that you can try it out. You
do this by adding an <APPLET> tag to the basic HTML shell. When you have completed this step,
you can run your applet using the Applet Viewer or from a J2SE v1.3-enabled Web browser.
This section describes how to create the basic HTML file and add the APPLET tag to it.
1. Create a file named Tutorial.html using your favorite text editor in your project
directory, Hello.
2. Enter the following HTML code to Tutorial.html, or paste it from Tutorial.html:
<HTML>
<!--Copyright 2000, Sun Microsystems, Inc. -->
<HEAD>
<TITLE>Getting Started with Java IDL: Running HelloApplet</TITLE>
<X-SAS-WINDOW TOP=42 BOTTOM=477 LEFT=4 RIGHT=534>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
-22-
Java IDL Tutorial and Guide
<HR>
<P>
<APPLET CODE=HelloApplet.class
CODEBASE='enter_the_path_to_your_project_directory_here'
WIDTH=500
HEIGHT=300>
<PARAM name="org.omg.CORBA.ORBInitialHost"
value=enter_server_machine_name>
<PARAM name="org.omg.CORBA.ORBInitialPort" value=1050>
</APPLET>
</BODY>
</HTML>
The simplest form of the APPLET tag tells the browser to load the applet whose Applet subclass is
name HelloApplet.class. When a Java-enabled browser encounters an <APPLET> tage, it
reserves a display area of the specified WIDTH and HEIGHT, loads the bytecode for the specifiec
Applet subclass, creates an instance of the subclass, and then calls the instances init method.
This applet includes PARAM tags, which let you customize the applet's configuration with
parameters. In the first PARAM tag, the value for ORBInitialHost is the name of the machine
where the CORBA name server runs. In this example, this will most likely be your local machine
name. In the second PARAM tag, the value of ORBInitialPort is the one you are using to run the
name server. This value was defined as 1050 earlier in this tutorial.
By default, a browser looks for an applet's class files in the same directory as the HTML file that
has the <APPLET> tag. We could use the CODEBASE attribute to tell the browser in which directory
the the applet's files are located. If the applet's files and the HTML file are in the same directory,
as they may be in this example, you can eliminate this attribute.
Now that you have the applet code and the HTML file that loads the applet, you are ready to run
your applet. For information on how to do this, link to Running the Hello World Applet.
Troubleshooting
If you are having trouble running the applet inside your Java-enabled Web browser, make sure
you have the JavaTM 2 Runtime Environment, Standard Edition, version 1.3.0, which includes the
JavaTM Plug-in 1.3. This can be downloaded from http://java.sun.com/products/plugi n/index.html.
Instructions for plugging it into your Web browser are available there as well.
Developing Clients
Covers topics of interest to CORBA client programmers
Exceptions: System Exceptions
-23-
Java IDL Tutorial and Guide
Explains how CORBA system exceptions work and provides details on the minor codes of
Java IDL's system exceptions
Initialization: System Properties
Explains what properties can be passed to the ORB at initialization
Naming Service
Covers the COS Naming Service in greater detail
This topic walks you through running the server and client program that together make up the
"Hello World" application or applet.
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. To run this
client-server application on your development machine:
1. Start the Java IDL Name Server. To do this from a UNIX command shell, enter:
In this example, port 1050 has been chosen for the naming service. You can change this to a
different value if port 1050 is occupied on your system. If the nameserverport is not
specified, port 900 will be chosen by default. 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.
On Unix:
On Windows:
You can leave out -ORBInitialPort nameserverport if the name server is running on the
default port.
If the Hello server is running on a different host (machine) than the naming service, you
would need to specify where the naming service is running when you start the server. To do
this, you would use the -ORBInitialHost nameserverhost argument.
You can leave out -ORBInitialPort nameserverport if the name server is running on the
default port.
-24-
Java IDL Tutorial and Guide
If the Hello client is running on a different host (machine) than the naming service, you
would need to specify where the naming service is running when you start the client. To do
this, you would use the -ORBInitialHost nameserverhost argument.
4. The client prints the string from the server to the command line:
Hello world!!
The name server and the Hello World server, like many CORBA servers, run until you explicitly
stop them. To avoid having many servers running, kill the server processes after the client
application returns successfully.
You can run the applet from either a Java-enabled Web browser (with JRE 1.3) or from the Applet
Viewer. In either case, you must run the Name Server and the HelloServer prior to invoking the
applet. To run the applet,
1. From an MS-DOS system prompt (Windows) or command shell (UNIX), start the Java IDL
name server:
On Unix:
On Windows:
In this example, the nameserverport, which is the port on which you want the name server
to run, is set to 1050. If you do not specify this, port 900 will be chosen by default. Also note
that 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.
On Unix:
On Windows:
In this example, the ORBInitialPort, which is the port on which you want the name
server to run, is set to 1050. If you do not specify this, port 900 will be chosen by default.
Also note that 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.
-25-
Java IDL Tutorial and Guide
<path_to_appletviewer_executable>appletviewer Tutorial.html
To run the applet from a Web browser, make sure you have the Java 2 Runtime
Environment, Standard Edition, version 1.3.0, which includes the Java Plugin 1.3,
and the latest version of your browser, preferably Netscape 6, then:
If the applet does not run in the Web browser, make sure you have the Java 2 Runtime
Environment, Standard Edition, version 1.3.0, which includes the Java Plugin 1.3. This plugin is
needed to run the applet and may not be present in older Web browsers.
The name server and the Hello World server, like many CORBA servers, run until you explicitly
stop them. To avoid having many servers running, kill the server processes after the client
application returns successfully.
Troubleshooting
Make sure you have the Java 2 Runtime Environment, Standard Edition, version 1.3.0, which
includes the Java Plugin 1.3. This plugin is needed to run the applet and may not be present in
older Web browsers. It can be downloaded from http://java.sun.com/products/plugin/index.html.
The default ORB Initial Port is port 900. If you prefer, you can omit the port specifications if you
start the name server on port 900. Using Solaris software, you must become root to start a process
on a port under 1024. Remember to exit from root access before continuing with the tutorial if you
choose this port for your name server.
To invoke an operation on a CORBA object, a client application needs a reference to the object. You
can get such references in a number of ways, such as calling
ORB.resolve_initial_references() or using another CORBA object (like the name service). In
previous sections of this tutorial, you used both of these methods to get an initial object reference.
Often, however, there is no naming service available in the distributed environment. In that
situation, CORBA clients use a stringified object reference to find their first object.
In this lesson, you will learn how to create a stringified object reference as a part of the server
startup, and how the client gets that reference and destringifies it for use as a real object
reference.
-26-
Java IDL Tutorial and Guide
To see completed versions of the source code, follow the links to HelloServer.java and
HelloClient.java.
For a stringified object reference to be available to the client, the server must create it and store it
somewhere that the client can access. Your reference will be written to disk in the form of a text
file.
1. Create a new directory at the same level as the Hello directory named HelloString. Copy
Hello.idl to this directory.
2. Copy HelloServer.java from the Hello directory to the HelloString directory. Name it
HelloServerString.java, and make the following changes in this file.
3. Because the new server will write a file to disk, you need to add an import statement. Add
the following:
4. The new server won't use the naming service, so you don't need the CosNaming packages.
Delete these lines from the code:
5. Delete the code that gets the initial naming context and resolves the reference to a Hello
object:
6. Call the ORB's object_to_string() method and pass it the reference to the servant
object. This returns the object reference in a string form that can be saved in a file on disk.
7. Build the path to the file that will be stored, using system properties to determine the path
structure and syntax.
-27-
Java IDL Tutorial and Guide
ps.close();
When HelloServerString runs, instead of calling the ORB and registering the servant object
with naming, it creates the text file HelloIOR containing a stringified reference to the servant. The
file is stored in your home directory.
Note to Windows users: You should substitute backslashes (\) for the slashes (/) in all paths in this
document.
1. Copy HelloClient.java from the Hello directory to the HelloString directory. Name it
HelloClientString.java, and make the following changes in this file.
2. Because the new client will read a file from the disk, you need to change the import
statements. Add the following:
3. The new client won't use the naming service, so you don't need the CosNaming package.
Delete this line from the code:
4. Delete the code that gets the initial naming context and registers the servant with the
naming service:
5. Use standard Java operations to read the file that has the object reference. Note that client
and server programs must know the name of the file and where it is stored.
The HelloClientString application now has a String object containing the stringified object
reference.
To destringify the object reference in ior, call the standard ORB method:
Finally, narrow the CORBA object to its proper type, so that the client can invoke on it:
-28-
Java IDL Tutorial and Guide
Compiling and running the new version of Hello World requires most of the same steps as for the
naming service version.
javac *.java
4. Correct any errors in your files and recompile if necessary. (You can copy the files from
HelloServer.java and HelloClient.java if you have trouble finding any typographical
errors.)
To be certain that you are running your own server, check that all Hello server and name server
processes have been stopped. Stop them if they are running.
1. From an MS-DOS system prompt (Windows) or command shell (UNIX), start the Hello
server with the stringified object reference:
2. From another prompt or shell, run the Hello application client with the stringified object
reference:
3. The client prints the string from the server to the command line:
Hello world!!
To enable the Hello World Tutorial to run on two machines, follow the steps as directed in the
tutorial, with the following changes. This tutorial was written for the Java (tm) 2 Platform,
Standard Edition (J2Se(tm)), version 1.3. In this example, the client, stubs, and skeletons are
-29-
Java IDL Tutorial and Guide
located on the client machine, and the server and name server are located on the server machine.
This scenario can be changed to meet your needs and is provided simply as an introduction to one
way this can be accomplished.
1. Create and compile the Hello.idl file on the client machine as indicated in the tutorial:
2. Create HelloClient.java on the client machine. Compile the .java files, including the stubs
and skeletons (which are in the directory HelloApp):
javac *.java
4. Start the Java IDL name server on the server machine. To do this on Unix:
To do this on Windows:
Note that the name server will run on port 1050 if you enter the command as listed. If you
want a different nameserverport, replace 1050 with the correct port number.
If you used a different nameserverport, replace 1050 with the correct port number.
6. On the client machine, run the Hello application client. From a DOS prompt or shell, type:
Note that nameserverhost is the host on which the IDL name server is running. In this
case, it is the server machine.
If you used a different nameserverport, replace 1050 with the correct port number.
Java IDL only supports transient objects - if an object's server process halts and restarts, the object
reference becomes invalid. However, Example 2 illustrates how a transient object can store its
state and re-initialize itself from this state each time the server is restarted.
The Example 2 server hosts a Hello object that stores a string in a file. You provide the string as a
command line argument to the client program. The server Hello object "remembers" the string and
-30-
Java IDL Tutorial and Guide
returns it to the client the next time that the client is run, even if the server has been stopped and
restarted.
Example 2 is identical to Example 1 except for the persistence enhancements. This page only
discusses the code neccessary to these enhancements.
module HelloApp
{
interface Hello
{
exception cantWriteFile{};
exception cantReadFile{};
string lastMessage()
raises (cantReadFile);
};
};
• Because the Hello object reads from and writes to a file, you will need to throw Java language
exceptions. (See Implementing the Server below). The Hello interface must define and raise
exceptions in order to generate the appropriate skeleton definitions.
• The sayHello method has been modified to take a string argument, which will be stored in a file
at runtime. A lastMessage method has been added to return this stored string to the client.
• The IDL compiler generates a directory HelloApp/HelloPackage that contains the following
exception class files:
cantReadFile.java
cantReadFileHelper.java
cantReadFileHolder.java
cantWriteFile.java
cantWriteFileHelper.java
cantWriteFileHolder.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
-31-
Java IDL Tutorial and Guide
import java.io.*;
-32-
Java IDL Tutorial and Guide
} catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
• The sayHello and lastMessage method implementations throw the exceptions defined in the
IDL file. These methods must throw file IO exceptions or the Java language compiler issues
warnings and errors.
• The HelloServant object receives ansychronous and possibly simultaneous method requests at
runtime. Therefore, you should enclose all file IO code in a synchronized clause.
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import java.io.*;
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
}
}
}
-33-
Java IDL Tutorial and Guide
• This client retrieves the stored message via lastMessage and stores the new message via an
argument to sayHello.
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 (\).
• Run the Hello application client from a different shell than the server:
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.
-34-
Java IDL Tutorial and Guide
module HelloApp
{
interface HelloCallback
{
void callback(in string message);
};
interface Hello
{
string sayHello(in HelloCallback objRef, in string message);
};
};
• 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.
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
-35-
Java IDL Tutorial and Guide
ncRef.rebind(path, helloRef);
} 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.
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
-36-
Java IDL Tutorial and Guide
}
}
}
• The HelloClient.main instantiates the callback object and passes it to the server. The client
must also register the callback object with the ORB.
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 (\).
• Run the Hello application client from a different shell than the server:
Ordinarily, servant classes must inherit from the ImplBase class generated by the idlj compiler.
This is inadequate for servant classes that need to inherit functionality from another Java class.
The Java programming language allows a class only one superclass and the generated ImplBase
class occupies this position.
Example 4 illustrates how a servant class can inherit (an implementation) from any Java class. In
this example, the HelloServant class inherits its entire implementation from another Java class
HelloBasic. At runtime, method requests for HelloServant are delegated to another idlj-
generated class.
-37-
Java IDL Tutorial and Guide
module HelloApp
{
interface Hello
{
string sayHello();
};
};
The files generated by this command are discussed in the basic tutorial.
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
class HelloBasic
{
public String sayHello()
{
return "\nHello world !!\n";
}
}
-38-
Java IDL Tutorial and Guide
} catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
-39-
Java IDL Tutorial and Guide
e.printStackTrace(System.out);
}
}
}
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 (\).
Then run the idlj compiler again to generate the Tie classes:
• Run the Hello application client from a different shell than the server:
13. Exceptions
CORBA has two types of exceptions: standard system exceptions which are fully specified by the
OMG and user exceptions which are defined by the individual application programmer. CORBA
exceptions are a little different from Java exception objects, but those differences are largely
handled in the mapping from IDL to Java.
-40-
Java IDL Tutorial and Guide
To specify an exception in IDL, the interface designer uses the raises keyword. This is similar to
the throws specification in Java. When you use the exception keyword in IDL you create a user-
defined exception. The standard system exceptions need not (and cannot) be specified this way.
System Exceptions
CORBA defines a set of standard system exceptions, which are generally raised by the ORB
libraries to signal systemic error conditions like:
All IDL operations can throw system exceptions when invoked. The interface designer need not
specify anything to enable operations in the interface to throw system exceptions -- the capability
is automatic.
This makes sense because no matter how trivial an operation's implementation is, the potential of
an operation invocation coming from a client that is in another process, and perhaps (likely) on
another machine, means that a whole range of errors is possible.
Therefore, a CORBA client should always catch CORBA system exceptions. Moreover, developers
cannot rely on the Java compiler to notify them of a system exception they should catch, because
CORBA system exceptions are descendants of java.lang.RuntimeException.
java.lang.Exception
|
+--java.lang.RuntimeException
|
+--org.omg.CORBA.SystemException
|
+--BAD_PARAM
|
+--//etc.
Minor Codes
All CORBA system exceptions have a minor code field, a number that provides additional
information about the nature of the failure that caused the exception. Minor code meanings are not
-41-
Java IDL Tutorial and Guide
specified by the OMG; each ORB vendor specifies appropriate minor codes for that
implementation. For the meaning of minor codes thrown by the Java ORB, see Minor code
meanings .
Completion Status
All CORBA system exceptions have a completion status field, indicating the status of the operation
that threw the exception. The completion codes are:
COMPLETED_YES
The object implementation has completed processing prior to the exception being raised.
COMPLETED_NO
The object implementation was not invoked prior to the exception being raised.
COMPLETED_MAYBE
The status of the invocation is unknown.
User Exceptions
java.lang.Exception
|
+--org.omg.CORBA.UserException
|
+-- Stocks.BadSymbol
|
+--//etc.
Each user-defined exception specified in IDL results in a generated Java exception class. These
exceptions are entirely defined and implemented by the programmer
System exceptions all have a field minor that allows CORBA vendors to provide additional
information about the cause of the exception. For a list of standard OMG minor code exceptions
(OMGVMCID), refer to the OMG document at http://cgi.omg.org/docs/omg/02-06-01.txt. If you
encounter a Sun minor code exception, email us for more information at javaidl@eng.sun.com.
14. Initialization
Before a Java program can use CORBA objects, it must initialize itself as follows:
-42-
Java IDL Tutorial and Guide
Before it can create or invoke a CORBA object, an applet or application must first create an ORB
object. Doing so introduces the applet or application to the ORB and obtains access to important
operations that are defined on the ORB object.
Applets and applications create ORB instances slightly differently, because their parameters,
which must be passed in the ORB.init() call, are arranged differently.
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORB;
Some web browsers have an ORB built directly into them. This can cause problems if that ORB is
not perfectly compliant. In this case, special steps must be taken to initialize the Java IDL ORB
specifically. For example, because of missing classes in the installed ORB in Netscape
Communicator 4.01, an applet displayed in that browser must contain code similar to the following
in its init() method:
import java.util.Properties;
import org.omg.CORBA.*;
Arguments to ORB.init()
For both applications and applets, the arguments for the initialization method are:
-43-
Java IDL Tutorial and Guide
args or this
Provides the ORB access to the application's arguments or applet's parameters.
null
A java.util.Properties object.
The init() operation uses these parameters, as well as the system properties, to obtain
information it needs to configure the ORB. It searches for ORB configuration properties in the
following places and order:
The first value found for a particular property is the value the init() operation uses. If a
configuration property cannot be found in any of these places, the init() operation assumes an
implementation-specific value for it. For maximum portability among ORB implementations,
applets and applications should explicitly specify configuration property values that affect their
operation, rather than relying on the assumptions of the ORB they happen to be running in.
System Properties
With respect to the system Properties object, note that Sun's Java virtual machine* adds -D
command line arguments to it. Other Java virtual machines may or may not do the same.
Currently, the following configuration properties are defined for all ORB implementations:
org.omg.CORBA.ORBClass
The name of a Java class that implements the org.omg.CORBA.ORB interface. Applets and
applications do not need to supply this property unless they must have a particular ORB
implementation. The value for the Java IDL ORB is com.sun.CORBA.iiop.ORB.
org.omg.CORBA.ORBSingletonClass
The name of a Java class that implements the org.omg.CORBA.ORB interface. This is the
object returned by a call to orb.init() with no arguments. It is used primarily to create
typecode instances than can be shared across untrusted code (such as unsigned applets) in
a secured environment.
In addition to the standard properties listed above, Java IDL also supports the following
properties:
org.omg.CORBA.ORBInitialHost
The host name of a machine running a server or daemon that provides initial bootstrap
services, such as a name service. The default value for this property is localhost for
applications. For applets it is the applet host, equivalent to getCodeBase().getHost().
org.omg.CORBA.ORBInitialPort
The port the initial naming service listens to. The default value is 900.
Note: When specifying a property as a command-line argument to a Java IDL application, omit
the org.omg.CORBA. portion of the property name. For example, a command line that starts an
application looks like this:
-ORBInitialPort 800
Applet parameters should specify the full property names. The conventions for applications differ
from applets so as not to expose language-specific details in command-line invocations.
-44-
Java IDL Tutorial and Guide
To invoke a CORBA object, an applet or application must have a reference for it. There are three
ways to get a reference for a CORBA object:
The first technique, converting a stringified reference to an actual object reference, is ORB-
implementation independent. No matter what Java ORB an applet or application runs on, it can
convert a stringified object reference. However, it is up to the applet or application developer to:
• Ensure that the object referred to is in fact accessible from where the applet or application
is running.
• Obtain the stringified reference, perhaps from a file or a parameter.
The following fragment shows how a server converts a CORBA object reference to a string:
This code fragment shows how a client converts the stringified object reference back to an object:
If you don't use a stringified reference to get an initial CORBA object, you use the ORB itself to
produce an initial object reference. However, doing so may make your applet or application ORB-
dependent, because, although the CORBA specification defines the interface for getting initial
object references, it doesn't yet provide enough information for ORB vendors to implement it in a
standard way. Applet and application developers should therefore be cautious when using this
operation until the standard is more tightly specified. To guarantee ORB-implementation-
independence, use the stringified object reference technique instead.
NameService
Passing this value returns a reference to a root naming context which, after narrowing, can
be used to look up references for objects whose names are known to the applet or
application (assuming those objects are registered by those names in the root or
subordinate naming contexts).
InterfaceRepository
This value returns a reference to an interface repository, a CORBA object that contains
interface definitions. The current release of Java IDL does not include an implementation
-45-
Java IDL Tutorial and Guide
of the interface repository. If you are using another server-side orb, you can still use
"InterfaceRepository" as the argument to resolve_initial_references().
*As used on this web site, the terms "Java Virtual Machine" or "JVM" mean a virtual machine
for the Java platform.
The CORBA COS (Common Object Services) Naming Service provides a tree-like directory for
object references much like a filesystem provides a directory structure for files. The Naming
Service provided with Java IDL is a simple implementation of the COS Naming Service
specification.
Object references are stored in the namespace by name and each object reference-name pair is
called a name binding. Name bindings may be organized under naming contexts. Naming contexts
are themselves name bindings and serve the same organizational function as a file system
subdirectory. All bindings are stored under the initial naming context. The initial naming context
is the only persistent binding in the namespace; the rest of the namespace is lost if the Java IDL
naming service process halts and restarts.
For an applet or application to use COS naming, its ORB must know the port of a host running a
naming service or have access to a stringified initial naming context for that naming service. The
naming service can either be the Java IDL naming service or another COS-compliant naming
service.
You must start the Java IDL naming service before an application or applet that uses its naming
service. Installation of the Java IDL product creates a script (Solaris: tnameserv) or executable file
(Windows NT: tnameserv.exe) that starts the Java IDL naming service. Start the naming service
so it runs in the background.
If you do not specify otherwise, the Java IDL naming service listens on port 900 for the bootstrap
protocol used to implement the ORB resolve_initial_references() and
list_initial_references() methods, as follows:
If you do not specify the name server port, port 900 is used by default. When running Solaris
software, you must become root to start a process on a port under 1024. For this reason, we
-46-
Java IDL Tutorial and Guide
recommend that you use a port number greater than or equal to 1024. To specify a different port,
for example, 1050, from a UNIX command shell, enter:
Clients of the name server must be made aware of the new port number. Do this by setting the
org.omg.CORBA.ORBInitialPort property to the new port number when creating the ORB object.
The -J option
To stop the Java IDL naming service, use the relevant operating system command, such as kill.
Note that names registered with the Java IDL naming service disappear when the service is
terminated.
The following sample program illustrates how to add names to the namespace. It is a self-
contained Naming Service client that creates the following simple tree.
In this example, plans is an object reference and Personal is a naming context that contains two
object references: calendar and schedule.
import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
-47-
Java IDL Tutorial and Guide
In the above section, Starting the Java IDL Naming Service, the nameserver was started on port
1050. The following code ensures that the client program is aware of this port number.
This code obtains the initial naming context and assigns it to ctx. The second line copies ctx into a
dummy object reference objref that we'll attach to various names and add into the namespace.
NamingContext ctx =
NamingContextHelper.narrow(orb.resolve_initial_references(
"NameService"));
NamingContext objref = ctx;
This code creates a name "plans" of type "text" and binds it to our dummy object reference. "plans"
is then added under the initial naming context using rebind. The rebind method allows us to run
this program over and over again without getting the exceptions we'd get from using bind.
This code creates a naming context called "Personal" of type "directory". The resulting object
reference, ctx2, is bound to the name and added under the initial naming context.
The remainder of the code binds the dummy object reference using the names "schedule" and
"calendar" under the "Personal" naming context (ctx2).
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
-48-
Java IDL Tutorial and Guide
{
public static void main(String args[])
{
try {
In the above section, Starting the Java IDL Naming Service, the nameserver was started on port
1050. The following code ensures that the client program is aware of this port number.
The list method lists the bindings in the naming context. In this case, up to 1000 bindings from
the initial naming context will be returned in the BindingListHolder; any remaining bindings are
returned in the BindingIteratorHolder.
This code gets the array of bindings out of the returned BindingListHolder. If there are no
bindings, the program ends.
Binding bindings[] = bl.value;
if (bindings.length == 0) return;
The remainder of the code loops through the bindings and prints the names out.
for (int i=0; i < bindings.length; i++) {
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
The Dynamic Skeleton Interface (DSI) allows servers to serve a servant object without prior
(compile time) knowledge of the object's interface. Insead of using skeleton code compiled from the
IDL interface definition, the server constructs an operation invocation dynamically.
-49-
Java IDL Tutorial and Guide
DSI can be used to bridge CORBA with non-CORBA environments. Such a bridge would allow
CORBA clients to invoke methods on CORBA objects that are implemented as, for example, COM
services.
The dynamic servant is implemented to convert the CORBA client request to a format understood
by the COM server. You must write all the code to perform this work. Contrast this with a typical
static object invocation. The server has access to the compiled skeletons for the interface being
invoked. These skeletons are generated by compiling the IDL interface definitions with the idlj
compiler. When the ORB receives a request, it uses the skeleton code to build operation arguments
on the server side and to send back any result.
module HelloApp
{
interface Hello
{
string printHelloArgs(in string arg1, in short arg2);
};
};
The following code is a shell implementation of a dynamic servant for the above interface. It is a
shell because only the basic compilable infrastructure for parsing method requests is provided. You
would need to insert code to implement a bridge.
import HelloApp.*;
import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import java.io.*;
import org.omg.CORBA.*;
-50-
Java IDL Tutorial and Guide
request.result(result_any);
}
}
catch (Exception ex) {
ex.printStackTrace();
System.out.println("DSIExample: Exception thrown: " + ex);
}
}
-51-
Java IDL Tutorial and Guide
OutputStream f = new
FileOutputStream(System.getProperty("user.home") +
System.getProperty("file.separator") + "DSI.ior");
DataOutputStream out = new DataOutputStream(f);
String ior = orb.object_to_string(helloRef);
out.writeBytes(ior);
out.close();
} catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
This release of the JavaTM 2 Platform, Standard Edition, v.1.3, includes idlj, a compiler that reads
an Object Management Group (OMG) Interface Definition Language (IDL) file and translates it, or
maps it, to a Java interface. The idlj compiler also creates stub, skeleton, helper, holder, and
other files as necessary. These .java files are generated from the IDL file according to the
mapping specified in the OMG document (pdf format) OMG IDL to Java Language Mapping
Specification, formal, 99-07-53. The postscript version of this specification can be found at
http://www.omg.org/technology/documents/formal/omg_idl_to_java_language_mapping.htm.
Formal specification 99-07-53 of the IDL to Java language mapping is aligned with CORBA version
2.3. For a basic summary of the IDL to Java mapping, see IDL to Java Language Mapping
Overview below.
Some topics from the OMG IDL to Java Language Mapping specification that are not easily
summarized are:
CORBA objects are defined in OMG IDL (Object Management Group Interface Definition
Language). J2SE v1.3 includes idlj, the IDL-to-Java compiler that maps the IDL-defined
interfaces to Java classes and interfaces.
This overview shows the correspondence between OMG IDL constructs and Java constructs. Note
that OMG IDL, as its name implies, defines interfaces. Like Java interfaces, IDL interfaces
contain no implementations for their operations (methods in Java). In other words, IDL interfaces
define only the signature for an operation (the name of the operation, the data type of its return
value, the data types of the parameters that it takes, and any exceptions that it raises). The
implementations for these operations need to be supplied in Java classes written by a Java
programmer.
-52-
Java IDL Tutorial and Guide
The following table lists the main constructs of IDL and the corresponding constructs in Java.
module package
boolean boolean
octet byte
float float
double double
fixed java.math.BigDecimal
exception class
operation method
Note: When a CORBA operation takes a type that corresponds to a Java object type (a String, for
example), it is illegal to pass a Java null as the parameter value. Instead, pass an empty version of
the designated object type (for example, an empty String or an empty array). A Java null can be
passed as a parameter only when the type of the parameter is a CORBA object reference or value
type, in which case the null is interpreted as a nil CORBA object reference.
-53-