Locating CORBA objects using Java IDL

Learn how to use stringification and the COS Naming Service to find CORBA objects spread around the enterprise

1 2 Page 2
Page 2 of 2
  • Initialization service -- The ORB class provides the org.omg.CORBA.Object resolve_initial_references(String name) method to obtain well-known services, where the name parameter specifies the requested service. Example services include the interface repository and the COS Naming Service. The name NameService requests a reference to the naming service. The following code demonstrates how to obtain a reference to the COS Naming Service:

    package ior;
    import org.omg.CosNaming.*;
    import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
    import org.omg.CosNaming.NamingContextPackage.CannotProceed;
    import org.omg.CosNaming.NamingContextPackage.NotFound;
    import org.omg.CORBA.*;
    public class NamingServer {   public static void main(String
     args[])   throws NotFound, CannotProceed,
     org.omg.CORBA.ORBPackage.InvalidName,
      org.omg.CosNaming.NamingContextPackage.InvalidName   {
          //initialize ORB
           ORB orb = ORB.init(args, null);
          //obtain reference to the naming service
          org.omg.CORBA.Object objRef;
          objRef = orb.resolve_initial_references(NS);
          //narrow reference to a NamingContext
          NamingContext ncRef; ncRef = NamingContextHelper.narrow(objRef);
          . . .   }
    }
    

    The ORB uses the parameters passed into init() to locate the COS Naming Service on the network. The Java IDL ORB looks for the following parameters:

    • org.omg.CORBA.ORBInitialHost -- The host where the naming service is running

    • org.omg.CORBA.ORBInitialPort -- The port where the naming service is listening

    When specifying these properties on the command line, you can omit the org.omg.CORBA portion of the property name, but the full name should be specified if setting applet parameters. The following invocation requests the ORB to locate the naming service on host steelrain at port 2345:

       C:>java ior.NamingClient -ORBInitialHost steelrain 
    -ORBInitialPort 2345
    

    By default, the Java IDL ORB attempts to locate the naming service on the localhost for applications and the codebase host for applets at port 900.

    As convenient as this mechanism is to locate the COS Naming Service, it is a proprietary solution. All ORBs will support the initialization service call but they locate services using proprietary techniques. The techniques discussed above for locating the Java IDL COS Naming Service using the Java IDL ORB do not work when using another vendor's ORB or naming service. If your applications must run in a multivendor environment, the next technique provides a mechanism for obtaining the initial naming context.

  • Naming context IOR -- Use the IOR that is printed out when the naming service is created to obtain a reference to the naming service using the stringification process described earlier.

    The tnameserv process prints its IOR and the TCP port on which it is listening when it is started:

    <tnameserv
    Initial Naming Context: IOR:000000000000002849444c3a6f6d672e6f72672f436f734e616d696e672f4
    e616d696e
    67436f6e746578743a312e3000000000010000000000000030000100000000000
    a737465
    656c7261696e0007f700000018afabcafe000000023be59816000000080000000
    00000000
    TransientNameServer: setting port for initial object
    references to: 900
    

Once the initial naming context is obtained, it must be narrowed to the org.omg.CosNaming.NamingContext type. The following snippet uses the IOR passed in as the first command-line parameter to locate the COS Naming Service:

package ior;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
public class IorNSClient {   public static void main(String 
args[])   throws NotFound, CannotProceed, InvalidName   {
      //initialize the ORB      ORB orb = ORB.init(args, null);
      org.omg.CORBA.Object ref;      NamingContext ncRef;
      //get naming context reference using IOR      String ior = 
args[0];      ref = orb.string_to_object(ior);
      //narrow reference to a NamingContext      ncRef = 
NamingContextHelper.narrow(ref);      . . .   }
}

Unlike the initialization service, using the IOR to locate the COS Naming service works with any combination of vendors' ORB and COS Naming Service implementations.

Resolving an object reference

Once the initial naming context is obtained, it can be used to locate registered objects. The NamingContext CORBA interface defines the methods for creating new subcontexts, registering CORBA objects, and locating CORBA objects:

  • bind() -- Creates a binding of a name and an object relative within a naming context

  • rebind() -- Unbinds the given name from an existing object (if such a binding is present) and binds it to a new object

  • resolve() -- Retrieves the object reference bound to the given name

  • new_context() -- Creates a new, unbound naming context

  • bind_context() -- Binds a new subcontext to the naming service; equivalent to creating a new subdirectory inside a directory

The following samples demonstrate how to use each method, and the following client-side code obtains a reference to the object using the compound name simple-object (where simple is a naming context and object is the binding of the CORBA object):

package ior;
import org.omg.CosNaming.*;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import ior.*;
public class NamingClient {
   public static void main(String 
args[])
   throws NotFound, CannotProceed, 
org.omg.CORBA.ORBPackage.InvalidName, 
org.omg.CosNaming.NamingContextPackage.InvalidName   {
      NamingContext ncRef = //get initial context here
      //create the naming path
      NameComponent name[] = { new
NameComponent("simple", ""),
         new NameComponent("object", "")
      }; 
      //resolve the path to a reference
      org.omg.CORBA.Object ref; SimpleObject obj;
      ref = ncRef.resolve(name); 
      obj = SimpleObjectHelper.narrow(ref);
      //invoke methods      obj.invoke();
   }
}

In a filesystem, concatenating the parent directory names and the filename together using a slash (this picks your direction) forms the path to a file. When using the naming service, the path to the object is formed using a sequence of NameComponent instances, where each NameComponent represents a binding within the naming hierarchy. Each NameComponent contains two strings: id and kind. The naming service does not use these strings except to ensure that each id is unique within the specified context. The id specifies the key value for the binding, while the kind provides a description (usually an empty string).

Binding an object

The following server-side code publishes the object retrieved in the previous example. Thus, it publishes a ior.SimpleObject implementation to the simple-object name within the naming service:

NamingContext ncRef = //get initial context here
NamingContext simpleCxt;
NameComponent simpleName[] = { new NameComponent("simple", "") };
simpleCxt = ncRef.new_context();
try {   ncRef.bind_context(simpleName, simpleCxt);
} catch(AlreadyBound ex) {   //already bound so resolve to it
instead objRef = ncRef.resolve(simpleName);   simpleCxt =
NamingContextHelper.narrow(objRef);
}
//export the object to the naming service
NameComponent objName[] = { new NameComponent("object", "") };
simpleCxt.rebind(objName, obj);

//block to prevent program from ending and wait for client
requests
System.out.println("Ready for client simple requests...");

This example uses a compound name that requires a little care. A real naming service implementation will support persistent names, which means a context can remain in existence long after the registered object has been removed from the name space. Your object registration code needs to handle the cases in which a parent naming context may or may not currently exist, and preserve all bindings if it does exist.

This example uses exception handling to efficiently handle both cases. The code assumes the simple context is not currently bound to the initial naming context and proceeds as follows:

  1. The application creates a one-element NameComponent array for the simple naming context binding.

  2. The application creates a new, unbound naming context by invoking the new_context() method on the root naming context. A NamingContext instance can only be created using another NamingContext.

  3. The new NamingContext is bound to the root naming context under the name simple using the bind_context() method.

  4. If a context is already bound to the simple name, the NamingContext bind_context() method generates an org.omg.CosNaming.CosNamingPackage.AlreadBound exception. Anticipating this problem, the program catches this exception (if it occurs) and resolves the existing context using resolve(), just like resolving a normal object.

Once the simple naming context is obtained from the naming service, a NameComponent array is built and bound using the NamingContext rebind() method.

Notice how NamingContext objects are published using the bind_context() method while all other CORBA objects are published using the bind() or rebind() methods. A NamingContext can be published using a bind() method, but it will not be usable as a naming context binding with the naming service.

Other naming approaches

If using an IOR is too crude and the COS Naming Service is too cumbersome, you may want to investigate the Java Naming and Directory Service (JNDI) or the Inprise Web Naming Service. JNDI provides a generic API for directory and naming services. The current incarnation of JNDI (as of mid-January) contains a beta implementation of a COS Naming Service provider. This provider enables you to bind, list, and resolve bindings using the standard JNDI API, which can be much more simple and elegant than using the standard org.omg.CosNaming package.

The Inprise Web Naming Service uses a Web server to manage and publish CORBA object IORs. This makes obtaining references as easy as specifying a URL and could potentially solve the problem of obtaining the initial naming context reference.

Both Inprise and Iona provide proprietary naming facilities through the use of binding an object to a name at the time of object construction. The name bindings are broadcast across the network through a proprietary communication scheme to all properly configured ORBs. The end result is a very easy-to-use naming service implementation in which the client application uses a single, lightweight bind() method to resolve to a specific object.

The limitations of this type of naming scheme are:

  1. Client hosts must be properly configured to receive binding broadcast notifications.

  2. An object can be bound to a single name only.

  3. Proprietary schemes will not work when using multiple-ORB implementations. This situation can occur when using ORBs built into commercial products such as Web browsers, database servers, and application servers along with your custom applications written using your company's standard ORB -- not to mention the combinations that result when integrating with your suppliers and customers.

Conclusion

CORBA provides two standard mechanisms for enabling client programs to obtain servant references: IORs and the COS Naming Service. As is normally the case with open standards, software vendors have developed additional naming service implementations. Choosing a naming service for your applications will depend on ORB vendor(s), network topology, existing company software architecture standards, and your level of aversion to "proprietary standards."

This article discussed four object reference resolution mechanisms:

IOR -- The only mechanism that is truly ORB-independent

COS Naming Service -- Provides scalability and robustness

Inprise Web Naming Service -- Uses a familiar naming convention (URLs) to publish and resolve references; potentially ORB-independent

Proprietary ORB naming services -- Provides a simple-to-program, robust naming solution

Good luck locating the object of your dreams.

Andy Krumel graduated from the US Naval Academy and started his career as a naval aviator. However, after a series of engine fires, radio failures, and assorted other mishaps, a career in computer programming looked more long-lived. Today, Andy is the founder of K&A Software, a rapidly growing, three-year-old Silicon Valley training and consulting firm specializing in Java and distributed applications. Andy and his cohorts will do just about anything to spread the word about Java's fantastic capabilities, from speaking at conferences, to teaching corporate training classes, to even writing an occasional article. When not pontificating, Andy is squirreled away creating solutions for one of K&A's corporate clients.

Learn more about this topic

  • Download the complete source in zip format. You will need Java 2 to run the code http://www.javaworld.com/jw-02-1999/enterprise/jw-02-enterprise.zip
  • Sun's Java IDL documentation, which includes documentation covering the Java IDL API, the naming service, creating and using CORBA object references, and an introductory tutorial http://java.sun.com/products/jdk/1.2/docs/guide/idl/index.html
  • Java 2 includes support for running CORBA server and client processes, including an implementation of a CORBA-compliant transient naming service http://java.sun.com/products/jdk/1.2/
  • Java 2 does not ship with an IDL-to-Java compiler so you must download it separately if you intend to develop and implement ORB-based services. Accessing this page requires you possess a Developer Connection account (joining is free) http://developer.java.sun.com/developer/earlyAccess/jdk12/idltojava.html
  • An excellent introductory tutorial to Java IDL is provided online in Sun's The Java Tutorial http://java.sun.com/docs/books/tutorial/idl/index.html
  • The Java Naming and Directory Interface (JNDI) is a standard Java extension and provides applications with a unified interface to multiple naming and directory services http://java.sun.com/products/jndi/index.html
  • The CORBA/IIOP 2.2 Specification is available online http://www.omg.org/corba/corbaiiop.html
  • The Iona OrbixNames, Iona's implementation of the COS Naming Service is documented online http://www.iona.com/products/sysman/orbixnames/fordevelopers.html
  • The VisiBroker Naming and Event Services, Inprise's implementation of the COS Naming Service, is documented online http://www.inprise.com/techpubs/books/vbnes/vbnes33/index.html
  • Read the first-ever Enterprise Java column,"Revolutionary RMIDynamic class loading and behavior objects," in the December issue of JavaWorld http://www.javaworld.com/jw-12-1998/jw-12-enterprise.html
1 2 Page 2
Page 2 of 2