CORBA-Java IDL-Java Meets CORBA - Part 3
17 Oct 1998Distributed-Computing
Stringified Object References
To invoke an operation on a CORBA object, a client application needs a reference to the server 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). Often, however, no Naming Service is available in the distributed environment. In this situation, CORBA clients use a stringified object reference to find their first object.
Although CORBA provides myriad ways for locating CORBA server objects, only one mechanism works for all IIOP-compliant CORBA implementations, Interoperable Object References (IORs). When working in a multiple-ORB environment, an IOR usually provides the only means to obtain an initial reference to an object, be it a Naming Service, transaction service, or customized CORBA servant.
ORBs supporting IIOP identify and publish object references using IORs. An IOR contains the information required for a client ORB to connect to a CORBA object or servant. Specifically, an IOR contains the following:
- IIOP version— Describes the IIOP version implemented by the ORB
- Host— Identifies the TCP/IP address of the ORB’s host machine
- Port— Specifies the TCP/IP port number where the ORB is listening for client requests
- Key—Identifies uniquely the servant to the ORB exporting the servant
- Components — Contains additional information applicable to object method invocations, such as supported ORB services and proprietary protocol support
Stringification is the process of converting a servant reference to and/or from a string representation of an IOR. Once an object reference has been stringified, it can be used by other applications to obtain a remote servant reference.
An IOR thus specifies the wire protocol for talking to an object, as well as specifying the object’s network location. The IOR structure isn’t important to programmers because an IOR is represented through a String instance by the process of stringification. IORs are convenient because they are easy to use and ORB-implementation-independent.
The InterestRates server example
In this section, we create a stringified object reference as a part of the server startup and show how the client gets that reference and destringifies it for use as a real object reference.
Define the IDL
The InterestRates Server Program has a single purpose in life. From one centralized server machine, it returns the current interest rates of different types of accounts a particular credit union provides. Clients can use these rates to perform their own computations. The IDL is defined in the Listing 5.
module Interest {
interface Rates {
float getPremiumChecking ();
float getPremiumSavings ();
float getEconomyChecking ();
float getEconomySavings ();
};
};
Listing 5: The Interrest Rates CORBA IDL
Code the server application
For a stringified object reference to be available to the client, the server must create the reference and store it somewhere the client can access. Our reference is written to disk in the form of a text file.
Because the new server will write a file to disk, the following import statement is added.
import java.io.*;
Define the servant class
We define the class for the servant object as follows.
class InterestRates extends _RatesImplBase {
private static final float _premiumChecking = 0.55f;
private static final float _premiumSavings = 2.10f;
private static final float _economyChecking = 0.20f;
private static final float _economySavings = 1.50f;
public float getPremiumChecking () { return _premiumChecking; }
public float getPremiumSavings () { return _premiumSavings; }
public float getEconomyChecking () { return _economyChecking; }
public float getEconomySavings () { return _economySavings; }
}
The servant is a subclass of _RatesImplBase so it inherits the general CORBA functionality generated for it by the compiler.
Making a stringified object reference
The new server won’t use the Naming Service, so we don’t need the CosNaming packages.
The call to the ORB’s object_to_string method passes 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 str = orb.object_to_string (ratesRef);
We then 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") + "RatesIOR";
Use standard Java operations to write the stringified IOR to disk:
FileOutputStream fos = new FileOutputStream (filename);
PrintStream ps = new PrintStream (fos);
ps.print (str);
ps.close ();
When the server runs, instead of calling the ORB and registering the InterestRates servant object with naming, it creates the text file RatesIOR containing a stringified reference to the servant. The file is stored in our home directory.
The complete source for the server is shown in the following Listing 6:
// Server.java, stringified object reference version
package ex2;
import java.io.*;
import org.omg.CORBA.*;
import Interest.*;
class InterestRates extends _RatesImplBase {
private static final float _premiumChecking = 0.55f;
private static final float _premiumSavings = 2.10f;
private static final float _economyChecking = 0.20f;
private static final float _economySavings = 1.50f;
public float getPremiumChecking () { return _premiumChecking; }
public float getPremiumSavings () { return _premiumSavings; }
public float getEconomyChecking () { return _economyChecking; }
public float getEconomySavings () { return _economySavings; }
}
public class Server {
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
InterestRates ratesRef = new InterestRates ();
orb.connect (ratesRef);
// stringify the ratesRef and dump it in a file
String str = orb.object_to_string (ratesRef);
String filename =System.getProperty ("user.home")+
System.getProperty("file.separator")+"RatesIOR";
FileOutputStream fos = new FileOutputStream (filename);
PrintStream ps = new PrintStream (fos);
ps.print (str);
ps.close ();
// Wait forever for current thread to die
Thread.currentThread ().join ();
} catch (Exception e) {
e.printStackTrace ();
}
}
}
Listing 6: The InterestRates CORBA server class
Code the client
Because the new server will write a file to disk, the following import statement is added.
import java.io.*;
Obtaining a stringified object reference
The new client won’t use the Naming Service, so we don’t need the CosNaming packages.
We use standard Java operations to read the file that has the object reference. Note, client and server programs must know the name of the file and where it is stored.
// Get the stringified object reference and destringify it.
String filename=System.getProperty ("user.home")+
System.getProperty ("file.separator")+"RatesIOR";
FileInputStream fis = new FileInputStream (filename);
DataInputStream dis = new DataInputStream (fis) ;
String ior = dis.readLine () ;
The client 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 the client can invoke operations on it:
Rates ratesRef = RatesHelper.narrow(obj);
The rest of the client code is self-explanatory. The complete client code is shown in the following Listing
// Client.java, stringified object reference version
package ex2;
import java.io.*;
import org.omg.CORBA.*;
import Interest.*;
public class Client {
public static void main (String args[]) {
try {
// create and initialize the ORB
ORB orb = ORB.init (args, null);
// Get the stringified object reference and destringify it.
String filename=System.getProperty ("user.home")+
System.getProperty ("file.separator")+"RatesIOR";
FileInputStream fis = new FileInputStream (filename);
DataInputStream dis = new DataInputStream (fis) ;
String ior = dis.readLine () ;
org.omg.CORBA.Object obj = orb.string_to_object (ior) ;
Rates ratesRef = RatesHelper.narrow (obj);
// call the Interest server object and print results
System.out.println ("Interest Rates provided by " +
"The Lake Side Credit Union\n");
System.out.println (" Premium Checkings Interest = " +
ratesRef.getPremiumChecking () + "%");
System.out.println (" Premium Savings Interest = " +
ratesRef.getPremiumSavings () + "%");
System.out.println (" Economy Checkings Interest = " +
ratesRef.getEconomyChecking () + "%");
System.out.println (" Economy Savings Interest = " +
ratesRef.getEconomySavings () + "%");
} catch (Exception e) {
e.printStackTrace ();
}
}
}
Listing 7: The InterestRates CORBA client
Start the CORBA InterestRates server
F:\>
F:\>java ex2.Server
Execute the InterestRates client
F:\>
F:\>java ex2.Client
Interest Rates provided by The Lake Side Credit Union
Premium Checkings Interest = 0.55%
Premium Savings Interest = 2.1%
Economy Checkings Interest = 0.2%
Economy Savings Interest = 1.5%
F:\>
You can always refer to my Homepage at webcornucopia.com for more CORBA source code. Another good resource is the comp-object-corba@omg.org mailing list from OMG. You can get the CORBA specs from omg.org.