Java IDL Tutorial and Guide -...

53
Java IDL Tutorial and Guide -1- Java IDL Tutorial and Guide 1. Getting Started with Java TM IDL 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. A one-method distributed object shared between a CORBA client and server. 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

Transcript of Java IDL Tutorial and Guide -...

Page 1: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-1-

Java IDL Tutorial and Guide 1. Getting Started with JavaTM IDL 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.

A one-method distributed object shared between a CORBA client and server.

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

Page 2: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-2-

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.

1. 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 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.

2. Compile the remote interface

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.

3. Implement the server

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.

4. Implement the client

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

Page 3: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-3-

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.

5. 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.

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.

For More Information

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.

2. Writing the Interface Definition Language (IDL) file

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.

These topics are included in this section:

1. Writing Hello.idl 2. Understanding the IDL file 3. Mapping Hello.idl to Java 4. Understanding the idlj Compiler Output

Page 4: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-4-

Writing Hello.idl

To create the Hello.idl file,

1. Create a new directory, named Hello, for this application. 2. Start your favorite text editor and create a file named Hello.idl in this directory. 3. In your file, enter the code for the interface definition:

module HelloApp { interface Hello { string sayHello(); }; };

4. Save the file.

Understanding the IDL file

OMG IDL is a purely declarative language designed for specifying programming-language-independent operational interfaces for distributed applications. OMG specifies a mapping from IDL to several different programming languages, including C, C++, Smalltalk, COBOL, Ada, and Java. When mapped, each statement in OMG IDL is translated to a corresponding statement in the programming language of choice. You can use the tool idlj to map an IDL interface to Java and implement the client class. When you map the same IDL to C++ and implement the server in that language, the Java client and C++ server interoperate through the ORB as though they were written in the same language.

The IDL for Hello World is extremely simple; its single interface has a single operation. You need perform only three steps:

1. Declare the CORBA IDL module 2. Declare the interface 3. Declare the operations

Declaring the CORBA IDL Module

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.

The module statement looks like this:

module HelloApp { // Subsequent lines of code here. };

When you compile the IDL, the module statement will generate a package statement in the Java code.

Declaring the Interface

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.

Page 5: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-5-

In your Hello.idl file, the interface statement looks like this:

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.

Declaring the Operations

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.

In your Hello.idl file, the operation statement looks like this:

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.

3. Mapping Hello.idl to Java

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.

1. Go to a command line prompt. 2. Change to the directory containing your Hello.idl file. 3. Enter the compiler command:

idlj -fall Hello.idl

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 */

Page 6: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-6-

public interface Hello extends HelloOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Hello

With an interface this simple, it is easy to see how the IDL statements map to the generated Java statements.

IDL Statement Java Statement

module HelloApp package HelloApp;

interface Hello public interface Hello

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 */ public interface HelloOperations { String sayHello (); } // interface HelloOperations

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.

IDL Statement Java Statement

string sayHello(); String sayHello();

Understanding the idlj Compiler Output

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

Page 7: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-7-

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

• Error Message: "idlj" not found

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.

For More Information

• Mapping IDL to Java: Overview

Provides the basics on mapping IDL constructs to the corresponding Java statements.

• Chapter 3 of the OMG CORBA/IIOP specification

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.

4. Developing the Hello World Server

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

Page 8: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-8-

extra code to deal with the ORB, with marshaling arguments and results, and so on, is provided by the server and the stubs.

The server class has the server's main() method, which:

• Creates an ORB instance • Creates a servant instance (the implementation of one CORBA Hello object) and tells the

ORB about it • Gets a CORBA object reference for a naming context in which to register the new CORBA

object • Registers the new object in the naming context under the name "Hello" • Waits for invocations of the new object

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

To see the complete version of HelloServer.java, follow the link.

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.

// The package containing our stubs. import HelloApp.*; // HelloServer will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*; public class HelloServer { public static void main(String args[]) { try{ // Create and initialize the ORB ORB orb = ORB.init(args, null); // Create the servant and register it with the ORB HelloServant helloRef = new HelloServant(); orb.connect(helloRef); // Get the root naming context

Page 9: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-9-

org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Bind the object reference in naming // Make sure there are no spaces between "" NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef); // Wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized(sync){ sync.wait(); } } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } } class HelloServant extends _HelloImplBase { public String sayHello() { return "\nHello world!!\n"; } }

3. Save and close HelloServer.java.

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.

Performing Basic Setup

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.

Importing Required Packages

First, we import the packages required for the server class:

// The package containing our stubs. import HelloApp.*; // HelloServer will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*;

Page 10: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-10-

Declaring the Server Class

The next step is to declare the server class:

public class HelloServer { // The main() method goes here. }

Defining the main() Method

Every Java application needs a main method. It is declared within the scope of the HelloServer class:

public static void main(String args[]) { // The try-catch block goes here. }

Handling CORBA System Exceptions

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.

The try-catch block is set up inside main(), as shown:

try{ // The rest of the HelloServer code goes here. } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); }

Creating an ORB Object

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.

ORB orb = ORB.init(args, null);

The call to the ORB's init() method passes in the server's command line arguments, allowing you to set certain properties at runtime.

Managing the Servant Object

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.

Page 11: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-11-

Instantiating the Servant Object

We instantiate the servant object inside the try-catch block, just below the call to init(), as shown:

HelloServant helloRef = new HelloServant();

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

Defining the Servant Class

At the end of HelloServer.java, outside the HelloServer class, we define the class for the servant object.

class HelloServant extends _HelloImplBase { // The sayHello() method goes here. }

The servant is a subclass of _HelloImplBase so that it inherits the general CORBA functionality generated for it by the compiler.

Next, we declare the required sayHello() method:

public String sayHello() { // The method implementation goes here. }

The sayHello() implementation looks like this:

return "\nHello world!!\n";

Working with COS Naming

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.

Obtaining the Initial Naming Context

In the try-catch block, below instantiation of the servant, we 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 a naming context object that is an object reference for the name service.

Page 12: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-12-

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. The call to narrow() is just below the previous statement:

NamingContext ncRef = NamingContextHelper.narrow(objRef);

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.

Registering the Servant with the Name Server

Just below the call to narrow(), we create a new NameComponent member:

NameComponent nc = new NameComponent("Hello", "");

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:

NameComponent path[] = {nc};

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.

Waiting for Invocation

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.

java.lang.Object sync = new java.lang.Object(); synchronized(sync){ sync.wait(); }

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.

Compiling the Hello World Server

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.

Page 13: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-13-

To compile HelloServer.java:

1. Change to the Hello directory. 2. Run the Java compiler on HelloServer.java:

javac HelloServer.java HelloApp/*.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.

Running the Hello World Server

The next section describes Running the Hello World Application.

For More Information

Exceptions: System Exceptions Explains how CORBA system exceptions work and provides details on the minor codes of Java IDL's system exceptions

Developing Servers Covers topics of interest to CORBA server programmers

Naming Service Covers the COS Naming Service in greater detail

5. Developing a Client Application

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

To see a completed version of HelloClient.java, follow the link.

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.

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. public class HelloClient { public static void main(String args[]) {

Page 14: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-14-

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 // make sure there are no spaces between "" NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // Call the Hello server object and print results String Hello = helloRef.sayHello(); System.out.println(Hello); } catch(Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); } } }

3. Save and close HelloClient.java.

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.

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 handle exceptions.

Importing Required Packages

First, we 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.

Declaring the Client Class

The next step is to declare the client class:

public class HelloClient { // The main() method goes here. }

Page 15: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-15-

Defining a main() Method

Every Java application needs a main() method. It is declared within the scope of the HelloClient class, as follows:

public static void main(String args[]) { // The try-catch block goes here. }

Handling CORBA System Exceptions

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.

The try-catch block is set up inside main(),

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.

The ORB variable is declared and initialized inside the try-catch block.

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

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.

Page 16: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-16-

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, 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.

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.

NamingContext ncRef = NamingContextHelper.narrow(objRef);

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.

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.

NameComponent nc = new NameComponent("Hello", "");

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:

NameComponent path[] = {nc};

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:

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.

Page 17: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-17-

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.

String Hello = helloRef.sayHello();

Finally, we print the results of the invocation to standard output:

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,

1. Change to the Hello directory. 2. Run the Java compiler on HelloClient.java:

javac HelloClient.java HelloApp/*.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.

Running the Client Application

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.

For More Information

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

6. Developing a Client Applet

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

Page 18: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-18-

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:

1. Creating the Applet 2. Understanding the Applet 3. Compiling and Running the Hello World Applet

To see a completed version of HelloApplet.java, follow the link.

Creating the Applet

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.

// The package containing our stubs. import HelloApp.*; // HelloClient will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*; // Needed for the applet. import java.awt.Graphics; public class HelloApplet extends java.applet.Applet { public void init() { try{ // Create and initialize the ORB // The applet 'this' is passed to make parameters from the tag // available to initialize the ORB ORB orb = ORB.init(this, null); // Get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Resolve the object reference in naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // Call the Hello server object and print the results message = helloRef.sayHello(); } catch(Exception e) {

Page 19: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-19-

System.out.println("HelloApplet exception: " + e); e.printStackTrace(System.out); } } String message = " "; public void paint(Graphics g) { g.drawString(message, 25, 50); } }

3. Save and close HelloApplet.java.

Understanding the Applet

This section explains each line of HelloApplet.java, describing what the code does, as well as why it is needed for this applet.

Performing Basic Setup

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.

Importing Required Packages

The first step to creating the basic shell of the applet is to import the packages required for the client class:

// The package containing our stubs. import HelloApp.*; // HelloClient will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*; // Needed for the applet. import java.awt.Graphics;

Declaring the Applet Class

Next, we declare the applet class:

public class HelloApplet extends java.applet.Applet { // The init() method goes here. }

Declaring the init() method

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

Page 20: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-20-

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.

public void init() { // The try-catch block goes here. }

Handling CORBA System Exceptions

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.

A try-catch block is set up inside init():

try{ // The rest of the HelloApplet code goes here. } catch(Exception e) { System.out.println("HelloApplet exception: " + 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 certain information about itself to the ORB.

You declare and initialize an ORB variable inside the try-catch block:

Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); ORB orb = ORB.init(this, props);

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.

Finding the Hello Server

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.

Page 21: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-21-

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, 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.

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. The call to narrow() is added just below the previous statement.

NamingContext ncRef = NamingContextHelper.narrow(objRef);

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.

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 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().

NameComponent nc = new NameComponent("Hello", "");

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:

NameComponent path[] = {nc};

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:

Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));

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.

Page 22: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-22-

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 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:

String message = " "; public void paint(Graphics g) { g.drawString(message, 25, 50); }

Compiling and Running the Hello World Applet

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.

Compiling the Client Applet

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

The generated file HelloApplet.class can be found in your project directory.

Setting Up the HTML File

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"> <H1 ALIGN=CENTER>Running the Hello World Applet</H1>

Page 23: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-23-

<HR> <P>If all goes well, the applet appears below: <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>

3. Save the file and exit the editor.

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.

Running the Applet

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.

On of the error messages indicative of this situation is security violation: method verification error.

For More Information

Developing Clients Covers topics of interest to CORBA client programmers

Exceptions: System Exceptions

Page 24: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-24-

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

7. Running the Hello World Application

This topic walks you through running the server and client program that together make up the "Hello World" application or applet.

Running the Hello World Application

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:

tnameserv -ORBInitialPort 1050&

From an MS-DOS system prompt (Windows), enter:

start tnameserv -ORBInitialPort 1050

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.

2. From a second prompt or shell, start the Hello server:

On Unix:

java HelloServer -ORBInitialPort 1050&

On Windows:

start java HelloServer -ORBInitialPort 1050

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.

3. From a third prompt or shell, run the Hello application client:

java HelloClient -ORBInitialPort 1050

You can leave out -ORBInitialPort nameserverport if the name server is running on the default port.

Page 25: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-25-

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.

Running the Hello World Applet

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:

tnameserv -ORBInitialPort 1050&

On Windows:

start tnameserv -ORBInitialPort 1050

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.

2. Start the Hello server:

On Unix:

java HelloServer -ORBInitialPort 1050 &

On Windows:

start java HelloServer -ORBInitialPort 1050

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.

3. Run the applet.

To run the applet from the appletviewer,

1. Change to the applet directory, Hello.

Page 26: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-26-

2. Start the appletviewer and browse Tutorial.html by typing:

<path_to_appletviewer_executable>appletviewer Tutorial.html

Hello world!! prints to the appletviewer frame.

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:

3. Open the Web browser. 4. Open the file Tutorial.html.

Hello world!! prints in the browser frame.

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

Security violation: method verification error

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.

Specifying ORB Initial Port

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.

8. Using Stringified Object References

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.

The steps in this lesson are:

1. Making a Stringified Object Reference

Page 27: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-27-

2. Getting a Stringified Object Reference 3. Destringifying the Object Reference 4. Compiling and Running a Stringified Hello World

To see completed versions of the source code, follow the links to HelloServer.java and HelloClient.java.

Making a Stringified Object Reference

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:

import java.io.*; // needed for output to the file system.

4. The new server won't use the naming service, so you don't need the CosNaming packages. Delete these lines from the code:

import org.omg.CosNaming.*; // not needed for stringified version import org.omg.CosNaming.NamingContextPackage.*; // remove from code

5. Delete the code that gets the initial naming context and resolves the reference to a Hello object:

// Get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Bind the object reference in naming NameComponent nc = new NameComponent("Hello", " "); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef);

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.

String ior = orb.object_to_string(helloRef);

7. Build the path to the file that will be stored, using system properties to determine the path structure and syntax.

String filename = System.getProperty("user.home")+ System.getProperty("file.separator")+"HelloIOR";

8. Use standard Java operations to write the stringified ior to disk:

FileOutputStream fos = new FileOutputStream(filename); PrintStream ps = new PrintStream(fos); ps.print(ior);

Page 28: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-28-

ps.close();

9. Save and close HelloServerString.java.

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.

Getting a Stringified Object Reference

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:

import java.io.*; // needed for input from the file system.

3. The new client won't use the naming service, so you don't need the CosNaming package. Delete this line from the code:

import org.omg.CosNaming;* // not needed for stringified version

4. Delete the code that gets the initial naming context and registers the servant with the naming service:

// Get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Resolve the object reference in naming NameComponent nc = new NameComponent("Hello", " "); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));

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.

String filename = System.getProperty("user.home")+ System.getProperty("file.separator")+"HelloIOR"; FileInputStream fis = new FileInputStream(filename); DataInputStream dis = new DataInputStream(fis); String ior = dis.readLine();

The HelloClientString application now has a String object containing the stringified object reference.

Destringifying the Object Reference

To destringify the object reference in ior, call the standard ORB method:

org.omg.CORBA.Object obj = orb.string_to_object(ior);

Finally, narrow the CORBA object to its proper type, so that the client can invoke on it:

Page 29: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-29-

Hello helloRef = HelloHelper.narrow(obj); The rest of the client code stays the same. Save and close HelloClientString.java.

Compiling and Running a Stringified Hello World

Compiling and running the new version of Hello World requires most of the same steps as for the naming service version.

Compiling Hello World

1. Change to the HelloString directory. 2. Compile the IDL file. Enter the compiler command:

idlj -fall Hello.idl

3. Run the Java compiler on your source code:

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

HelloServerString.class, HelloServantString.class, and HelloClientString.class are generated to the HelloString directory.

Running Hello World

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:

java HelloServerString -ORBInitialPort 1050 &

2. From another prompt or shell, run the Hello application client with the stringified object reference:

java HelloClientString -ORBInitialPort 1050 &

3. The client prints the string from the server to the command line:

Hello world!!

For More Information

Initialization: Obtaining Initial Object References Explains the various ways of getting an initial object reference

9. The "Hello World" Example on 2 machines

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

Page 30: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-30-

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:

idlj -fall Hello.idl

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 HelloApp/*.java

3. Create HelloServer.java on the server machine. Compile the .java files:

javac *.java

4. Start the Java IDL name server on the server machine. To do this on Unix:

tnameserv -ORBInitialPort 1050&

To do this on Windows:

start tnameserv -ORBInitialPort 1050

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.

5. On the server machine, start the Hello server, as follows:

java HelloServer -ORBInitialPort 1050

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:

java HelloClient -ORBInitialHost namerserverhost -ORBInitialPort 1050

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.

7. Kill or stop the server process when finished.

10. Hello World with Persistent State

This document has not been updated for J2SE 1.3

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

Page 31: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-31-

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.

This page contains:

• The IDL for the persistent "Hello World" program • A transient server that creates an object, registers it in a naming context, and saves its

state in a file. • An application client.

Instructions for compiling and running the example are provided.

Interface Definition (Hello.idl)

module HelloApp { interface Hello { exception cantWriteFile{}; exception cantReadFile{}; string sayHello(in string message) raises (cantWriteFile); 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

Use of these classes is illustrated in the implementation below.

Implementing the Server (HelloServer.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*;

Page 32: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-32-

import java.io.*; class HelloServant extends _HelloImplBase { public String sayHello(String msg) throws HelloApp.HelloPackage.cantWriteFile { try { synchronized(this) { File helloFile = new File("helloStorage.txt"); FileOutputStream fos = new FileOutputStream(helloFile); byte[] buf = new byte[msg.length()]; msg.getBytes(0, msg.length(), buf, 0); fos.write(buf); fos.close(); } } catch(Exception e) { throw new HelloApp.HelloPackage.cantWriteFile(); } return "\nHello world !!\n"; } public String lastMessage() throws HelloApp.HelloPackage.cantReadFile { try { synchronized(this) { File helloFile = new File("helloStorage.txt"); FileInputStream fis = new FileInputStream(helloFile); byte[] buf = new byte[1000]; int n = fis.read(buf); String lastmsg = new String(buf); fis.close(); return lastmsg; } } catch(Exception e) { throw new HelloApp.HelloPackage.cantReadFile(); } } } public class HelloServer { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // create servant and register it with the ORB HelloServant helloRef = new HelloServant(); orb.connect(helloRef); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // bind the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef);

Page 33: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-33-

// wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } } • The sayHello 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.

• No changes are required to HelloServer.main.

Implementing the Client (HelloClient.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; import java.io.*; public class HelloClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // call the Hello server object and print results String oldhello = helloRef.lastMessage(); System.out.println(oldhello); String hello = helloRef.sayHello(args[0]); System.out.println(hello); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }

Page 34: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-34-

• This client retrieves the stored message via lastMessage and stores the new message via an argument to sayHello.

Building and Running Hello World

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

• Create source files as shown above.

• Run idlj on the IDL file to create stubs and skeletons:

idltojava -fall Hello.idl

• Compile the .java files, including the stubs and skeletons:

javac *.java HelloApp/*.java

• Make sure the name server is running:

tnameserv -ORBInitialPort 1050&

• Start the Hello server:

java HelloServer -ORBInitialPort 1050

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

java HelloClient "remember this message" -ORBInitialPort 1050

11. Hello World with Callback Object

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

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

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

This page contains:

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

Instructions for compiling and running the example are provided.

Page 35: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-35-

Interface Definition (Hello.idl)

module HelloApp { interface HelloCallback { void callback(in string message); }; interface Hello { string sayHello(in HelloCallback objRef, in string message); }; }; • A HelloCallback is defined, which the client will implement.

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

Implementing the Server (HelloServer.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; class HelloServant extends _HelloImplBase { public String sayHello(HelloCallback callobj, String msg) { callobj.callback(msg); return "\nHello world !!\n"; } } public class HelloServer { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // create servant and register it with the ORB HelloServant helloRef = new HelloServant(); orb.connect(helloRef); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // bind the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc};

Page 36: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-36-

ncRef.rebind(path, helloRef); // wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } } • The sayHello method implementation has been modified to invoke the callback object that it receives.

Implementing the Client (HelloClient.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; class HelloCallbackServant extends _HelloCallbackImplBase { public void callback(String notification) { System.out.println(notification); } } public class HelloClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); HelloCallbackServant helloCallbackRef = new HelloCallbackServant(); orb.connect(helloCallbackRef); // call the Hello server object and print results String hello = helloRef.sayHello(helloCallbackRef,"\ntest..\n"); System.out.println(hello); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out);

Page 37: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-37-

} } } • The client implements the HelloCallbackServant object.

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

Building and Running Hello World

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

• Create the source code files as shown above.

• Run idlj on the IDL file to create stubs and skeletons:

idlj -fall Hello.idl

• Compile the .java files, including the stubs and skeletons:

javac *.java HelloApp/*.java

• Make sure the name server is running:

tnameserv -ORBInitialPort 1050&

• Start the Hello server:

java HelloServer -ORBInitialPort 1050

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

java HelloClient -ORBInitialPort 1050

12. Hello World with Implementation Inheritance

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.

Example 4 is identical to Example 1 except for implementation inheritance enhancements. This page only discusses the code necessary for these enhancements.

This section contains:

Page 38: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-38-

• The IDL for a simple "Hello World" program • A server implementation that delegates method requests for HelloServant to another

Java class. • A client program.

Instructions for compiling and running the example are provided.

Interface Definition (Hello.idl)

module HelloApp { interface Hello { string sayHello(); }; };

Compile the IDL interface with the command:

idlj -fall Hello.idl

The files generated by this command are discussed in the basic tutorial.

Then use the compiler again to generate the Tie bindings:

idlj -fallTIE Hello.idl The second command generates an additional file in a HelloApp subdirectory: Hello_Tie.java

This class acts as the skeleton, receiving invocations from the ORB and delegating them to the servant that actually does the work.

Implementing the Server (HelloServer.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; class HelloBasic { public String sayHello() { return "\nHello world !!\n"; } } class HelloServant extends HelloBasic implements HelloOperations { } public class HelloServer { public static void main(String args[]) { try{ // create and initialize the ORB

Page 39: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-39-

ORB orb = ORB.init(args, null); // create servant and register it with the ORB HelloServant servant = new HelloServant(); Hello helloRef = new Hello_Tie(servant); orb.connect(helloRef); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // bind the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef); // wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }

Implementing the Client (HelloClient.java)

// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class HelloClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // call the Hello server object and print results String hello = helloRef.sayHello(); System.out.println(hello); } catch (Exception e) { System.out.println("ERROR : " + e) ;

Page 40: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-40-

e.printStackTrace(System.out); } } }

Building and Running Hello World

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

• Create source code files as shown above.

• Run idlj on the IDL file to create stubs and skeletons:

idlj -fall Hello.idl

Then run the idlj compiler again to generate the Tie classes:

idlj -fallTIE Hello.idl

• Compile the .java files, including the stubs and skeletons:

javac *.java HelloApp/*.java

• Make sure the name server is running:

tnameserv -ORBInitialPort 1050&

• Start the Hello server:

java HelloServer -ORBInitialPort 1050

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

java HelloClient -ORBInitialPort 1050

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.

Topics in this section include:

• Differences Between CORBA and Java Exceptions • System Exceptions

o System Exception Structure o Minor Codes o Completion Status

• User Exceptions • Minor Code Meanings

Page 41: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-41-

Differences Between CORBA and Java Exceptions

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:

• Server-side system exceptions, such as resource exhaustion or activation failure. • Communication system exceptions, for example, losing contact with the object, host down,

or cannot talk to ORB daemon (orbd). • Client-side system exceptions, such as invalid operand type or anything that occurs before

a request is sent or after the result comes back.

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.

System Exception Structure

All CORBA system exceptions have the same structure:

exception <SystemExceptionName> { // descriptive of error unsigned long minor; // more detail about error CompletionStatus completed; // yes, no, maybe }

System exceptions are subtypes of java.lang.RuntimeException through org.omg.CORBA.SystemException:

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

Page 42: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-42-

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

CORBA user exceptions are subtypes of java.lang.Exception through org.omg.CORBA.UserException:

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

Minor Code Meanings

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 [email protected].

14. Initialization

Before a Java program can use CORBA objects, it must initialize itself as follows:

• Create an ORB object. • Obtain one or more initial object references, typically at least a naming context.

Topics in this section include:

• Creating an ORB Object o Creating an ORB for an Application o Creating an ORB for an Applet o Arguments to ORB.init() o System Properties

• Obtaining Initial Object References o Stringified Object References o Getting References from an ORB

Page 43: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-43-

Creating an ORB Object

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.

Creating an ORB for an Application

This fragment shows how an application might create an ORB:

import org.omg.CORBA.ORB; public static void main(String args[]) { try{ ORB orb = ORB.init(args, null); // code continues

Creating an ORB for an Applet

An applet creates an ORB like this:

import org.omg.CORBA.ORB; public void init() { try { ORB orb = ORB.init(this, null); // code continues

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.*; public class MyApplet extends java.applet.Applet { public void init() { // Instantiate the Java IDL ORB, passing in this applet // so that the ORB can retrieve the applet properties. Properties props = new Properties(); props.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); ORB orb = ORB.init(this, props); ... } }

Arguments to ORB.init()

For both applications and applets, the arguments for the initialization method are:

Page 44: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-44-

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:

1. The application or applet parameters (first argument) 2. A java.util.Properties object (second argument), if one has been supplied 3. The java.util.Properties object returned by System.getProperties()

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.

Page 45: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-45-

Obtaining Initial Object References

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:

• From a string that was specially created from an object reference • From another object, such as a naming context • From the ORB operation resolve_initial_references()

Stringified Object References

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:

org.omg.CORBA.ORB orb = // get an ORB object org.omg.CORBA.Object obj = // create the object reference String str = orb.object_to_string(obj); // make the string available to the client

This code fragment shows how a client converts the stringified object reference back to an object:

org.omg.CORBA.ORB orb = // get an ORB object String stringifiedref = // read string org.omg.CORBA.Object obj = orb.string_to_object(stringifiedref);

Getting References from an ORB

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.

The ORB interface defines an operation called resolve_initial_references() that is intended for bootstrapping object references into a newly started application or applet. The operation takes a string argument that names one of a few recognized objects; it returns a CORBA Object, which must be narrowed to the type the applet or application knows it to be. Two string values are presently defined:

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

Page 46: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-46-

of the interface repository. If you are using another server-side orb, you can still use "InterfaceRepository" as the argument to resolve_initial_references().

The Java IDL implementation of resolve_initial_references() requires an already-running naming service whose host and port are identified by the ORBInitialHost and ORBInitialPort properties described previously, or by their default values. See Naming Service for details on starting the Java IDL name server.

*As used on this web site, the terms "Java Virtual Machine" or "JVM" mean a virtual machine for the Java platform.

15. Naming Service

Topics in this section include:

• Java IDL Naming Service • Starting the Java IDL Naming Service • Stopping the Java IDL Naming Service • Sample Client: Adding Objects to the Namespace • Sample Client: Browsing the Namespace

Java IDL Naming Service

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.

Starting the Java IDL 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:

tnameserv -ORBInitialPort nameserverport

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

Page 47: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-47-

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:

tnameserv -ORBInitialPort 1050

From an MS-DOS system prompt (Windows), enter:

start tnameserv -ORBInitialPort nameserverport

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

This command-line option is available for use with tnameserve. -Joption

Pass option to the Java virtual machine, where option is one of the options described on the reference page for the java application launcher. For example, -J-Xms48m sets the startup memory to 48 megabytes. It is a common convention for -J to pass options to the underlying virtual machine.

Stopping the Java IDL Naming Service

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.

Sample Client: Adding Objects to the Namespace

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.*; public class NameClient { public static void main(String args[]) { try {

Page 48: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-48-

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. Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); ORB orb = ORB.init(args, props); 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. NameComponent nc1 = new NameComponent("plans", "text"); NameComponent[] name1 = {nc1}; ctx.rebind(name1, objref); System.out.println("plans rebind sucessful!"); 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. NameComponent nc2 = new NameComponent("Personal", "directory"); NameComponent[] name2 = {nc2}; NamingContext ctx2 = ctx.bind_new_context(name2); System.out.println("new naming context added.."); The remainder of the code binds the dummy object reference using the names "schedule" and "calendar" under the "Personal" naming context (ctx2). NameComponent nc3 = new NameComponent("schedule", "text"); NameComponent[] name3 = {nc3}; ctx2.rebind(name3, objref); System.out.println("schedule rebind sucessful!"); NameComponent nc4 = new NameComponent("calender", "text"); NameComponent[] name4 = {nc4}; ctx2.rebind(name4, objref); System.out.println("calender rebind sucessful!"); } catch (Exception e) { e.printStackTrace(System.err); } } }

Sample Client: Browsing the Namespace

The following sample program illustrates how to browse the namespace.

import java.util.Properties; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class NameClientList

Page 49: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-49-

{ 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. Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); ORB orb = ORB.init(args, props); The following code obtains the intial naming context. NamingContext nc = NamingContextHelper.narrow(orb.resolve_initial_references( "NameService")); 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. BindingListHolder bl = new BindingListHolder(); BindingIteratorHolder blIt= new BindingIteratorHolder(); nc.list(1000, bl, blIt); 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++) { // get the object reference for each binding org.omg.CORBA.Object obj = nc.resolve(bindings[i].binding_name); String objStr = orb.object_to_string(obj); int lastIx = bindings[i].binding_name.length-1; // check to see if this is a naming context if (bindings[i].binding_type == BindingType.ncontext) { System.out.println( "Context: " + bindings[i].binding_name[lastIx].id); } else { System.out.println("Object: " + bindings[i].binding_name[lastIx].id); } } } catch (Exception e) { e.printStackTrace(System.err); } } }

16. The Dynamic Skeleton Interface (DSI)

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.

Page 50: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-50-

Why Use DSI?

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.

Dynamic Servant Implementation Example

Consider the following interface:

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.

// Copyright and License import HelloApp.*; import java.util.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import java.io.*; import org.omg.CORBA.*; // servant must extend DynamicImplementation class HelloServant extends DynamicImplementation { // store the repository ID for the implemented interface

Page 51: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-51-

static String[] myIDs = {"IDL:JavaIDL/DSIExample:1.0"}; ORB orb; // create a reference to the ORB HelloServant(ORB orb) { this.orb = orb; } // must implement invoke() for handling requests public void invoke(ServerRequest request) { try { System.out.println("DSI: invoke called, op = "+request.op_name()); // create an NVList to hold the parameters NVList nvlist = orb.create_list(0); // need an if statement like this for each method name if (request.op_name().equals("printHelloArgs") == true) { // need an Any for each argument Any any1 = orb.create_any(); any1.insert_string(""); nvlist.add_value("arg1", any1, ARG_IN.value); Any any2 = orb.create_any(); any2.insert_string(""); nvlist.add_value("arg2", any2, ARG_IN.value); // pass the NVList to the request to get values request.params(nvlist); System.err.println("Argument 1: In value: " + nvlist.item(0).value().extract_string()); System.err.println("Argument 2: In value: " + nvlist.item(1).value().extract_short()); TypeCode result_tc = orb.get_primitive_tc(TCKind.tk_void); Any result_any = orb.create_any(); result_any.type(result_tc); request.result(result_any); } } catch (Exception ex) { ex.printStackTrace(); System.out.println("DSIExample: Exception thrown: " + ex); } } // implement an _ids method to return repository ID of interface public String[] _ids() { return myIDs; } // HelloServer implemented in the usual fashion 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

Page 52: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-52-

HelloServant helloRef = new HelloServant(orb); orb.connect(helloRef); 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(); System.out.println("IOR is "+ ior); // wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }

17. IDL to Java Language Mapping

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:

• Section 1.19, Mapping Pseudo-Objects to Java • Section 1.20, Server-Side Mapping • Section 1.21, Java ORB Portability Interfaces

IDL to Java Language Mapping Overview

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.

Page 53: Java IDL Tutorial and Guide - paginas.fe.up.ptpaginas.fe.up.pt/~nflores/dokuwiki/lib/...20tutorial_20and_20guide.pdf · Java IDL Tutorial and Guide -3- the name service provided with

Java IDL Tutorial and Guide

-53-

The following table lists the main constructs of IDL and the corresponding constructs in Java.

IDL Construct Java Construct

module package

interface (non-abstract) signature interface and an operations interface, helper class, holder class

interface (abstract) signature interface, helper class, holder class

constant (not within an interface) public interface

boolean boolean

char, wchar char

octet byte

string, wstring java.lang.String

short, unsigned short short

long, unsigned long int

long long, unsigned long long long

float float

double double

fixed java.math.BigDecimal

enum, struct, union class

sequence, array array

exception class

readonly attribute accessor method

readwrite attribute accessor and modifer methods

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.