IDL
Contents
- What is Java IDL?
- The CORBA Architecture
- The Java IDL Development Process
- Writing the IDL Interface
- Developing a Client Application
- Developing the Hello World Server
- Compiling and Running the Hello World Application
- Using Stringified Object References
- Glossary
What is Java IDL?
Java 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. CORBA and the IDL mappings are the work of an industry consortium known as the OMG, or Object Management Group. Sun is a founding member of the OMG, and the Java IDL team has played an active role in defining the IDL-to-Java mapping.
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. If this is starting to seem like alphabet soup, hold on: background details on CORBA, IDL, and the ORB are coming up in the next section.
This trail walks you through designing and developing a simple pair of interacting Java IDL applications. It starts by showing you the general architecture of CORBA, then follows with an overview of the steps to building CORBA applications in Java IDL. Finally, it takes you through each step to produce a running server and client that interact using CORBA.
The CORBA Architecture
Servers provide remote interfaces. Clients call remote interfaces.
The terms client and server define object-level rather than application-level interaction.
Applications be servers for some objects and clients of others. 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.
Client applications reference remote objects using stub methods. Stubs are 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 CORBA-compliant ORBs pass information back and forth. Like CORBA and IDL, the IIOP standard is defined by OMG, the Object Management Group.
In addition to these simple distributed object capabilities, CORBA-compliant ORBs can provide a number of optional services defined by the OMG. These include services for looking up objects by name, maintaining persistent objects, supporting transaction processing, enabling messaging, and many other abilities useful in today's distributed, multi-tiered computing environments. Several Java ORBs from third-party vendors support some or all of these additional capabilities. The ORB provided with Java IDL supports one optional service, the ability to locate objects by name.
The Java IDL Development Process
- Define the Remote Interface
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
idltojava 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
idltojava compiler over those interfaces and follow the steps for creating the client or server described in this trail.- Compile the remote interface
When you run the
idltojava 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.- Implement the server
Once you run the
idltojava 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.- Implement the client
Similarly, you use the stubs generated by the
idltojava compiler as the basis of your client application. The client code builds on the stubs to start its ORB, look up the server using the name service provided with Java IDL, obtain a reference for the remote object, and call its method.- Start the applications
Once you implement a server and a client, you can start the name service, then start the server, then run the client.
Hello World Example
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. CORBA terminology and the underlying functionality of the application is discussed in The CORBA Architecture.
- The client (applet or application) invokes the
sayHello operation of the HelloServer.- The ORB transfers that invocation to the servant object registered for that IDL interface
- The servant's
sayHello method runs, returning a JavaString.- The ORB transfers that
String back to the client.- The client prints the value of the
String.
Getting Started
Before you start working with Java IDL, you need two things: version 1.2 of the JDK software and theidltojava compiler. The JDK provides the API and ORB needed to enable CORBA-based distributed object interaction. Theidltojava 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. Click here to download and install the idltojava compiler.The Java 2 Platform, Standard Edition, v. 1.3, now includes a new version of the IDL-to-Java compiler, idlj. The idlj compiler replaces the idltojava compiler that was available as a separate download in previous releases. You can download the Java 2 Platform, Standard Edition, v. 1.3and visit Java IDL Documentation for more information on Java IDL in the 1.3 release.
Developing a Client Application
This lesson introduces the basics of writing a CORBA client application. Here's the completed version of HelloClient.javaWhile this lesson focuses on writing a CORBA client application, many of the steps are identical to those required for writing applets. The major difference is that the applet code appears in the init method rather than in main. For information on how to set up the applet's HTML page, see Setting Up the HTML File (Applets Only). Here's the complete code for the applet version: HelloApplet.java
Performing Basic Setup
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 remember to handle any exceptions.
Importing Required Packages
Start your text editor and save a new file titledHelloClient.java to your project directory.Import the packages required for the client class:
import HelloApp.*; // The package containing our stubs. import org.omg.CosNaming.*; // HelloClient will use the naming // service. import org.omg.CORBA.*; // All CORBA applications need these // classes.If you are writing an applet, you also need to import java.awt.Graphics and org.omg.CosNaming.NamingContextPackage.*. The latter package contains special exceptions thrown by the name service.
Declaring the Client Class
In HelloClient.java, declare the client class:public class HelloClient { // Add the main method here in the next step. }In the applet version of this code, HelloApplet.java, you declare the applet class like this:
public class HelloApplet extends java.applet.Applet {
// Put the init() method here in the next step.
}
Defining a main Method
Every Java application needs a main method. Declare it within the scope of the HelloClient class, as follows:public static void main(String args[]) { // Put the try-catch block here in the next step. }
Handling CORBA System Exceptions
Because all CORBA programs can throw CORBA system exceptions at runtime, you will place all of the main functionality within a try-catch block. CORBA programs throw system exceptions whenever trouble occurs during any of the processes involved in invoking the server from the client.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.
Inside main, set up a try-catch block:
try { // Add the rest of the HelloClient code here. } catch(Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); }
Creating an ORB Object
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.InsideHelloClient.java's try-catch block, declare and initialize an ORB variable:
ORB orb = ORB.init(args, null);The call to the ORB's init method passes in your application's command line arguments, allowing you to set certain properties at runtime.
Finding the Hello Server
Once 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 no naming service is available.
Obtaining the Initial Naming Context
The first step in using the naming service is to get the initial naming context. In the try-catch block, below your ORB initialization, call orb.resolve_initial_references to get an object reference to the name server: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.org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
Narrowing the Object Reference
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. Add the call to narrow just below the previous statement.NamingContext ncRef = NamingContextHelper.narrow(objRef);Here we see the use of an idltojava -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.
Finding a Service in Naming
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. Add this code directly below the call to narrow.
NameComponent nc = new NameComponent("Hello", "");This statement sets the id field of nc, the new NameComponent, to "Hello" and the kind field to an empty string.
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:
NameComponent path[] = {nc};Finally, 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:
Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));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.
Invoking the sayHello Operation
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.
- Continuing with the try-catch block in HelloClient.java, enter the following invocation below the call to the name service's resolvemethod:
String hello = helloRef.sayHello();- Finally, add code to print the results of the invocation to standard output:
System.out.println(hello);- Save and close HelloClient.java.
Setting Up the HTML File (Applets Only)
Tutorial.html is provided for displaying your finished applet, but you need to customize a few attributes and parameters.
- Open Tutorial.html in your text editor.
- Inside the APPLET tag, enter the path to your project directory as the value for the CODEBASE attribute.
- In the first PARAM tag, enter the name of the machine where the CORBA name server runs (most likely your local machine name) as the value for ORBInitialHost.
- Make sure the second PARAM tag is set to the value of ORBInitialPort that you are using to run the name server (it's preset to 1050 to work with the default used in the examples in this trail). In any case, it should be a value above 1028.
Now you're ready to write the server code.