Naming Service


Topics in this section include:

COS Naming Service: an Overview

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 an implementation of the COS Naming Service specification. The following overview is taken from that document.

A name-to-object association is called a name binding. A name binding is always defined relative to a naming context. A naming context is an object that contains a set of name bindings in which each name is unique. Different names can be bound to an object in the same or different contexts at the same time.

To resolve a name is to determine the object associated with the name in a given context. To bind a name is to create a name binding in a given context. A name is always resolved relative to a context - there are no absolute names.

Because a context is like any other object, it can also be bound to a name in a naming context. Binding contexts in other contexts creates a naming graph - a directed graph with nodes and labeled edges where the nodes are contexts. A naming graph allows more complex names to reference an object. Given a context in a naming graph, a sequence of names can reference an object. This sequence of names (called a compound name) defines a path in the naming graph to navigate the resolution process.

The following figure shows an example of a naming graph. A sample program that illustrates how to add names to the namespace uses this same model.

For an application to use the COS Naming Service, 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.

Prior to running a client or a server, you will start ORBD. ORBD includes a persistent Naming Service and a transient Naming Service, both of which are an implementation of the COS Naming Service.

Both client and server should agree on which root naming context to use. The orb.resolve_initial_references(String name_of_service) method is used to obtain the root naming context. If you get a handle on a Naming Service by providing "NameService" as the name_of_service, you will get a persistent naming service, meaning that the naming context graph will be restored after a service failure. If you get the handle using "TNameService", you will get a transient naming service, meaning that you will need to re-obtain the root naming context using orb.resolve_initial_references(String name_of_service) if there is a service interruption.

For example,

      // get the root naming context
      org.omg.CORBA.Object objRef =
          orb.resolve_initial_references("NameService");
      NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

The string "NameService" is defined for all CORBA ORBs. When you pass in this string, the ORB returns a naming context object that is an object reference for:

To specify that you want to use the transient naming service with ORBD, pass in the string "TNameService". The string "TNameService" is a proprietary name. When you pass in this string, the ORB returns a naming context object that is an object reference for ORBD's transient name service.

As with all CORBA object references, objRef is a generic CORBA object. To use it as a NamingContextExt object, you must narrow it to its proper type.

NamingContextExtHelper is an idlj-generated helper class, similar in function to HelloHelper. The ncRef object is now an org.omg.CosNaming.NamingContextExt and you can use it to access the naming service and register the server.

NamingContextExt and NamingContextExtHelper are new to this release of J2SE. NamingContextExt is the extension of NamingContext. It contains a set of name bindings in which each name is unique and is part of the Interoperable Naming Service. Different names can be bound to an object in the same or different contexts at the same time. Using NamingContextExt, you can use URL-based names to bind and resolve. NamingContextExtHelper provides additional helper methods like narrow() that are type-specific but don't deal with business logic.

Interoperable Naming Service

The Interoperable Naming Service (INS) is a URL-based naming system on top of the CORBA Naming Service, as well as a common bootstrap mechanism that lets applications share a common initial naming context.

The Interoperable Naming Service (INS) provides the following features:

An example application that demonstrates how to use the INS can be found at Interoperable Naming Service Example.

The following diagram shows how INS fits into ORBD:

ORBD



An object reference contains at least three pieces of information: an address, the name of the POA that created an object reference, and an Object ID.

Using INS, you can provide a URL to access the CORBA object, which is more readable than a stringified IOR. The following stringified object reference formats are allowed:

Bootstrap Options for the ORB

INS provides ORB options for bootstrapping. To bootstrap a CORBA system, you must give it an object reference. The ORB can be configured to return the handle of a customized CORBA service from resolve_initial_references() using either ORBInitRef and/or ORBDefaultInitRef. For example,

The order of resolution when these options are used is as follows:

  1. Objects registered with register_initial_references
  2. -ORBInitRef
  3. -ORBDefaultInitRef
  4. Proprietary Bootstrap (Sun ORBs only)

For more information about INS, refer to the OMG specification at (ptc/00-08-07).

Using the Naming Service

To use the Naming Service, you must first write the server and client code that finds and/or creates the namespace and/or the objects in the namespace. Before running the client and server, you must start the Naming Service and tell the client and server where to find it. The following steps loosely suggest what happens when the client and server attempt to access the Naming Service:

The following topics are covered in this section:

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. Naming contexts are in italics and object references are in normal font.

In this example, plans is an object reference and Personal is a naming context that contains two object references: calendar and schedule.

  1. Create the NameClient.java file and import the proper libraries:

    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClient
    {
       public static void main(String args[])
       {
          try {
    

  2. Set Port and Host properties.

    In the section, Starting the Naming Service, the name server is started on port 1050 and host localhost. The following code ensures that the client program is aware of this port number and host name.

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

  3. Obtain the initial naming context.

    The following 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.

     
            NamingContextExt ctx =
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
            org.omg.CORBA.Object objref = ctx;
    

  4. Bind the name "plans" to the object reference.

    This code binds the name "plans" to our dummy object reference. The 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 name1[] = ctx.to_name("plans");
            ctx.rebind(name1, objref);
            System.out.println("plans rebind successful!");
    

  5. Create a new naming context named "Personal".

    This code creates a new naming context called "Personal". The resulting object reference, ctx2, is bound to the name and added under the initial naming context.

            NameComponent name2[] = ctx.to_name("Personal");
            NamingContextExt ctx2 = (NamingContextExt)ctx.bind_new_context(name2);
            System.out.println("New naming context, Personal, added!");
    

  6. Bind "schedule" and "calendar" to a dummy object reference. To bind a name is to create a name binding in a given context. A name is always resolved relative to a context - there are no absolute names.

    This code binds the dummy object reference using the names "schedule" and "calendar" under the "Personal" naming context (ctx2).

            NameComponent name3[] = ctx.to_name("schedule");
            ctx2.rebind(name3, objref);
            System.out.println("schedule rebind successful!");
    
            NameComponent name4[] = ctx.to_name("calendar");
            ctx2.rebind(name4, objref);
            System.out.println("calendar rebind successful!");
    
    
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
      }  
    }
    

  7. Save NameClient.java, and compile the file as follows:

         javac NameClient.java
    

    Correct any syntax errors before proceeding.

  8. Run the Object Request Broker Daemon as shown in Starting the Naming Service.

  9. Run NameClient, as follows:

         java NameClient -ORBInitialPort 1050
    

The output in the terminal window looks like this:

We now have a namespace that to the Naming Service looks like the above diagram.

Sample Client: Resolving Objects from the Namespace

The following sample program illustrates how to resolve names from the namespace. To resolve a name is to determine the object associated with the name in a given context. When using the persistent Naming Service, you do not need to re-resolve if the Naming Service goes down. If you use a transient Naming Service, you do need to re-resolve in the Naming Service goes down.

In this example, plans is an object reference and Personal is a naming context that contains two object references: calendar and schedule.

  1. Create the NameClientResolve.java file and import the proper libraries:

    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClientResolve
    {
       public static void main(String args[])
       {
          try {
    

  2. Set Port and Host properties.

    In the section, Starting the Naming Service, the name server is started on port 1050 and host localhost. The following code ensures that the client program is aware of this port number and host name.

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

  3. Obtain the initial naming context.

    The following code obtains the initial naming context and assigns it to nc.

     
            NamingContextExt nc =
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
    

  4. Resolve each namespace.

    The following code resolves each namespace.

       org.omg.CORBA.Object sched = nc.resolve_str("Personal/schedule");
            org.omg.CORBA.Object cal = nc.resolve_str("Personal/calendar");
            org.omg.CORBA.Object plan = nc.resolve_str("plans");
    
          //finish the try-catch block
          } catch (Exception e) {
            e.printStackTrace(System.err);
            } 
    }
    

  5. Save NameClientResolve.java, and compile the file as follows:

         javac NameClientResolve.java
    

    Correct any syntax errors before proceeding.

  6. Make sure the Object Request Broker Daemon is running and the client application illustrated in Sample Client: Adding Objects to the Namespace has been run.

  7. Run NameClientResolve, as follows:

         java NameClientResolve -ORBInitialPort 1050
    

There is no output to the terminal window when you run this client application. If you want verification that the object references have been resolved, you could add code such as the following for testing purposes:

	if (sched == null){
	  System.out.println("Schedule is null");
	}
		
	if (cal == null){
	  System.out.println("Calendar is null");
	}
	 
	if (plan == null){
	  System.out.println("Plans is null");
	}

Sample Client: Browsing the Namespace

The following sample program illustrates how to browse the namespace.

  1. Create the NameClientList.java file and import the proper libraries:

    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClientList
    {
       public static void main(String args[])
       {
          try {
    

  2. In the section, Starting the Naming Service, the nameserver is started on port 1050 and host localhost. The following code ensures that the client program is aware of this port number and host name.

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

  3. Obtain the initial naming context.

            NamingContextExt nc = 
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
    
    

  4. List all bindings in the naming context.

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

  5. Get the array of bindings.

    This code gets the array of bindings out of the returned BindingListHolder.

            Binding bindings[] = bl.value;
    
    
    

  6. This code loops through the bindings and prints the names out.
            for (int i=0; i < bindings.length; i++) {
    
                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);
           } 
       }
    }
    

  7. Save NameClientList.java, and compile the file as follows:

         javac NameClientList.java
    

    Correct any syntax errors before proceeding.

  8. Make sure the Object Request Broker Daemon is running, the client application illustrated in Sample Client: Adding Objects to the Namespace has been run, and the client application illustrated in Sample Client: Resolving Objects from the Namespace has been run.

  9. Run NameClientList, as follows:

         java NameClientList -ORBInitialPort 1050
    

The output in the terminal window looks like this:

Starting the Naming Service

In all of the tutorials we use the Object Request Broker Daemon, orbd, which includes both a Persistent and a Transient Naming Service, and is available with every download of J2SE 1.4 and higher.

For a caller (client, peer, or client application) to be able to invoke a method on a remote object, that caller must first obtain a reference to the remote object.

Once a remote object is registered on the server, callers can look up the object by name, obtain a remote object reference, and then remotely invoke methods on the object.

To learn how to start the Naming Service, see the topic Starting the Naming Service in the ORBD documentation.

Stopping the Naming Service

To stop the naming service, use the relevant operating system command, such as kill on Solaris, or Ctrl+C in the DOS window in which orbd is running. Note that names registered with the naming service may disappear when the service is terminated if the naming service is transient. The Java IDL naming service will run until it is explicitly stopped.

Naming Service FAQ

How do I connect to a 3rd-party Naming Service from Sun's ORB?

The recommended way is to use the Inter-Operable Naming Service (INS), if this option is supported by the 3rd-party Naming Service.

To use the Sun ORB with another vendor's Naming Service,

  1. Start the 3rd-party name server on Host and Port.

  2. Pass the following argument to ORB.init():
            -ORBInitRef NameService=corbaloc:iiop:1.2@:

    /NameService

When you do orb.resolve_initial_references( "NameService" ), you should be able to connect to 3rd-party Name Service. If you are still not able to connect, try these troubleshooting hints:


Java IDL Home