Netscape Internet Service Broker for Java: Programmer's Guide, Version 1.0

[Contents] [Previous] [Next]

Chapter 3
Naming and Binding to Objects

This chapter describes techniques for naming and operating on objects, object references, and interfaces. It includes the following major sections:

Web Naming Service

The Web Naming Service enables you to associate a Uniform Resource Locator (URL) with an object. Once a URL has been bound to an object, clients can obtain a reference to the object by specifying the URL as a string instead of the object's name. This feature enables client applications to locate objects provided by any vendor.

The key methods are provided by the netscape.WAI.Naming class. This class is part of the nisb.zip file in the Netscape Enterprise Server and the iiop10.jar file in Netscape Communicator. The methods behave slightly differently depending on which ORB is used. Differences are described below.

register

This method uses WebNaming to register an object with a URL of the form http://host[:port]/path/name. The caller's machine must be allowed to do an HTTP 'PUT' on the designated host.

Calling register using the Enterprise Server's ORB is different than calling register using the Communicator's ORB. With the Enterprise Server, this call automatically prepends NameService/ to the specified path/name. For example:

register("http://mikelee/HelloService", service);
registers the object with the following (automatically modified) URL:

http://mikelee/NameService/HelloService
With the Communicator, the URL is not automatically modified, so you need to specify the NameService/ prefix yourself. For example:

register("http://mikelee/NameService/HelloService", service);
If the object has already been registered with a URL, this method replaces (overwrites) the old URL with a new one.

resolve

This method resolves a CORBA object from a URL of the form http://host[:port]/path/name.

Calling resolve using the Enterprise Server's ORB is different than calling resolve using the Communicator's ORB. With the Enterprise Server, this call automatically prepends NameService/ to the specified path/name. For example:

obj = resolve("http://mikelee/HelloService");
resolves a CORBA object using the following (automatically modified) URL:

http://mikelee/NameService/HelloService
With the Communicator, the URL is not automatically modified, so you need to specify the NameService/ prefix yourself. For example:

obj = resolve("http://mikelee/NameService/HelloService");
The following code examples show how these methods are used by clients and services. The first example is part of a service application that calls register to register a service with the Enterprise Server's ORB.

// Part of a service application using the Enterprise Server's ORB.
public class HelloService extends _sk_HelloWorld {
   public static void main(String args[]) {
      // Initialize the BOA because we are going to accept connections.
      BOA boa = orb.BOA_init();
      /* Create the service. */
      HelloService service = new HelloService();
      /* Expose the service to the net. */
      boa.obj_is_ready(service);
      /* Register the service. */
      try {
         String host =
            java.net.InetAddress.getLocalHost().getHostName();
         Naming.register("http://" + host + "/HelloService", service);

         // For the Communicator's ORB this call would be:
         // Naming.register("http://" + host +
         //                 "/NameService/HelloService", service);

      } catch (Exception e)
      { e.printStackTrace();
        System.exit( -1 );
      }
      /* Wait for requests. */
      boa.impl_is_ready();
   }
}
Following is part of a client applet that calls resolve to find a service, given a URL. Applets always use the Communicator's ORB.

// Part of a client applet using the Communicator's ORB.
public class HelloClientApplet extends java.applet.Applet {
   org.omg.CORBA.ORB orb;
   HelloWorld hello;
   public void init() {
      /* Initialize the ORB. */
      orb = org.omg.CORBA.ORB.init();
      /* Resolve an object. */
      // String host = getCodeBase().getHost();
      String host = "myServer.nscp.com";
      // From applets you can only use the Communicator's ORB.
      String url_string = "http://" + host +
         "/NameService/HelloService";
      org.omg.CORBA.Object obj = Naming.resolve(url_string);
      /* In some cases (where multiple CORBA interfaces
         are implemented), casting requires a query to the
         remote host. So we call 'narrow' to cast here. */
      hello = HelloWorldHelper.narrow(obj);
      if(hello == null)
         unableToLocate(url_string); // bad cast returns null
      setLayout(new GridLayout(1,1));
      Button b = new Button("GO!");
      add(b);
   }
}

Operations on Object References

Given an object reference, a client can invoke methods defined in that object's IDL specification. In addition, all objects derived from the class org.omg.CORBA.Object inherit methods that you can use to manipulate the object. Some of these methods are listed below; for a complete discussion of these and other methods, see the Netscape Internet Service Broker for Java Reference Guide.

NOTE: You cannot use the instanceof keyword to determine the runtime type.

Table 3.1 From org.omg.CORBA.Object, methods on object references
Method Description
_clone

Creates a copy of the object. It also creates another TCP/IP connection.

_is_a

Determines whether an object implements a specified interface.

_is_bound

Returns true if a connection is currently active for this object.

_is_equivalent

Returns true if two objects refer to the same interface implementation.

_is_local

Returns true if this object is implemented in the local address space.

_is_remote

Returns true if this object's implementation resides on a remote host.

_object_name

Returns this object's name.

Converting an Object Reference to a String

Object references are opaque and can vary from one ORB to another, so ISB for Java provides methods that allow you to convert an object reference to a string as well as convert a string back into an object reference. The CORBA specification refers to this process as "stringification."

Method Description
object_to_string

Converts an object reference to a string.

string_to_object

Converts a string back to an object reference.

Narrowing Object References

The process of converting an object reference's type from a general super-type to a more specific sub-type is called narrowing.

NOTE: You cannot use the Java casting facilities for narrowing.
ISB for Java maintains a typegraph for each object interface so that narrowing can be accomplished by using the object's narrow method. If the narrow method determines it is not possible to narrow an object to the type you request, it will return NULL.

The narrow method generated for the AccountManager.

abstract public class AccountManagerHelper {
  ...
  public static Bank.AccountManager narrow(org.omg.CORBA.Object object) {
      ...
  }
  ...
}

Interface and Object Names

Interface names and object names enable a client to use multiple instances of a service.

Interface Names

When you define an object's interface in an IDL specification, you give it an interface name. For example, the following IDL code specifies interfaces named Account and AccountManager.

module Bank {
    interface Account {
        float balance();
    };
    interface AccountManager {
        Account open(in string name);
    };
};

Object Names

When creating an object, a service application must specify an object name to make it available to clients. When the service calls BOA.object_is_ready, the service's interface name is registered only if the object is named. Objects that are given an object name when they are created return persistent object references. See Object and Implementation Activation for a complete discussion of persistent and transient objects. To make a client use a specific service, provide an object name. Also, a client must specify object names to bind to more than one instance of a service at a time. The object name distinguishes between multiple instances of a service. If an object name is not specified, the ORB will return any suitable object with the specified interface.

Using Qualified Object Names with Servers

Consider a banking application where you need to have two AccountManager objects available; one for a bank in Chicago and one for another bank in Dallas. You may even want to implement two separate object servers, possibly on different hosts. Each server could instantiate its own AccountManager object, but each would use the AccountManager constructor that accepts an object name. The following code examples show the server code for creating AccountManagers named Dallas and Chicago, and the client code to connect to the Dallas AccountManager.

Creating AccountManagers with the object names Dallas and Chicago.

// Using Enterprise Server's ORB
public class Server {
  public static void main(String[] args) {
    try {
      // Initialize the ORB.
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
       // Initialize the BOA.
      org.omg.CORBA.BOA boa = orb.BOA_init();
      // Create the account manager objects.
      AccountManager dalMngr= new AccountManager("Dallas");
      AccountManager chiMngr= new AccountManager("Chicago");
      // Export the newly created objects.
      boa.obj_is_ready(dalMngr);
      boa.obj_is_ready(chiMngr);

      // Or, if using Communicator's ORB, the call would be:
      // netscape.WAI.Naming.register
      //    ("http://myServer.nscp.com/NameService/Dallas", dalMngr);

      netscape.WAI.Naming.register
         ("http://myServer.nscp.com/Dallas", dalMngr);
      netscape.WAI.Naming.register
         ("http://myServer.nscp.com/Chicago", chiMngr);

      // Optional status messages.
      System.out.println(dalMngr + " is ready.");
      System.out.println(chiMngr + " is ready.");
      // Wait for incoming requests.
      boa.impl_is_ready();
    } catch (org.omg.CORBA.SystemException se) {
        System.err.println(se);
    }
  }
}
A client binding to an AccountManager with the object name Dallas.

// Using Enterprise Server's ORB
public class Client {
  public static void main(String args[]) {
    try {
      // Initialize the ORB.
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
      // Locate an account manager named Dallas.
      // Or, if using Communicator's ORB, the urlStr should be:
      //    "http://myServer.nscp.com/NameService/Dallas";
      String urlStr = "http://myServer.nscp.com/Dallas");
      org.omg.CORBA.Object obj = netscape.WAI.Naming.resolve(urlStr);
      Bank.AccountManager manager =
         Bank.AccountManagerHelper.narrow(obj);
      // Use args[0] as the account name, or a default.
      String name = args.length > 0 ? args[0] : "Jack B. Quick";
      // Request the account manager to open a named account.
      Bank.Account account = manager.open(name);
      // Get the balance of the account.
      float balance = account.balance();
      // Print out the balance.
      System.out.println
        ("The balance in " + name + "'s account is $" + balance);
    } catch (org.omg.CORBA.SystemException(se) {
        System.err.println(se);
    }
  }
}


[Contents] [Previous] [Next]

Last Updated: 02/04/98 13:46:50


Copyright © 1997 Netscape Communications Corporation

Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use