★ wanayoo — archive 1999 http://developer.iplanet.com/docs/technote/components/corba/naming.htmNouvelle recherche | Portail wanayoo
         downloads
 technologies
 support
 
   
Home
Resources
  Code Samples
  TechNotes
  View Source
  Newsgroups
  Tech Support
  White Papers
  Technical Books
Using Naming Service: Accessing CORBA Objects

By Mike S. Lee
Technology Evangelist

This Netscape TechNote explains how to use the Naming Service provided with Netscape ISB to access CORBA Objects from Java, JavaScript and C++. Make sure you have already enabled CORBA by following the TechNote, "Enabling CORBA on Enterprise Server"

ABSTRACT

This Netscape TechNote will explore the Naming Service provided with Netscape ISB, the ORB shipped with Enterprise Server 3.x and Communicator 4.x.  We will demonstrate how to use the Naming Service to bind and resolve CORBA object references using Java, JavaScript, and C++.  Please note that an application may be both a client (user of a CORBA Object) and a server (a CORBA Object).


TABLE OF CONTENTS


INTRODUCTION

Naming Service is a CORBAservice that allows components on the object bus to locate other components on the object bus by a user definable name.  Netscape Enterprise Web servers and Netscape Communicator contain methods that allow you to access the naming services built into the web server. These naming services allow you to associate a URL with an object. Once the URL is associated with the object, any client of the web server can access the object reference through the URL.

One big difference is that for Java register and resolve calls the behavior in the Enterprise Server's ORB libraries are different from the Communicator's ORB libraries.  Communicator ORB's register/resolve internally uses the HTTP PUT/GET methods to place the reference to the CORBA object on  a web server.  Enterprise Server ORB's register/resolve internally uses CosNaming to access the Naming Service.  Note that the register call from the Communicator's ORB can be used to placed the IOR on any web server that allows web publishing.  And the resolve call from the Communicator's ORB can be used to get an IOR from any web server.  See the Naming Service APIs for the exact differences.

The registerObject call is more tied to the Enterprise Server.  Since it uses the Enterprise Server's naming service directly by using CosNaming and will only work if
you are using Enterprise Server as the Web Server.

I've been using registerObject when using the Enterprise Server's ORB and register when I use the Communicator's ORB (NameUtil class is not available with the
Communicator's ORB).

Here's the general mapping for registering and resolving.  See the Naming Service APIs for the exact mapping details.

CORBA Objects should always be mapped under the path /NameService.

    http://<hostAndPort>/NameService/<object_name>
      OR

    http://<hostAndPort>/NameService/WAS/<object_name>

Please see the WAI documentation for more information on the Naming Service.
 


WHAT IS WAI and WAS?

WAI, Web Application Interface, is the API to extend Enterprise Server functionality.  WAS, Web Application Service, is the application that is written using WAI.  Enterprise Server 3.0x and later will use WAI as the primary API to extend server functionality.  Please see WAI documentation for more details.

Q. Why is WAI mentioned in a CORBA TechNote?
A. WAI is implemented using CORBA.  Hence, the pre-requisites and documentation for setting up CORBA and WAI overlap.


WHERE IS OSAGENT?

OSAgent is the Naming Service provided by Visigenic VisiBroker.  With Enterprise Server 3.0, OSAgent can be used as the Naming Service.  However from Enterprise Server 3.0c + WAI Patch and later, OSAgent is no longer supported.  The Naming Service APIs described in this TechNote should be used instead.

Q. OSAgent was so easy to use, why did Netscape take it out of Enterprise Server?
A. The use of OSAgent by-passed the security model provided by the web server.  Removal of OSAgent allows the Enterprise Server's Naming Service to utilize the security features provided by Enterprise Server.  In this way, the Naming Service becomes just another web resource that can be control by Enterprise Server's Access Control Lists.


PRE-REQUISITES
To use CORBA and the Naming Service: To develop and run Java/C/C++ applications for use with Enterprise Server ORB:
  • For Java: Set CLASSPATH to include <server_root>/wai/java/nisb.zip;<server_root>/wai/java/WAI.zip
  • For Java/C/C++ see the WAI documentation, specifically Using WAI.
To develop Java applications and applets for use with the Communicator ORB:
  • Set CLASSPATH to include <comm_root>/Program/Java/Classes/java40.jar;<comm_root>/Program/Java/Classes/iiop10.jar
To run Java applications and applets for use with the Communicator ORB:
  • Application: Set CLASSPATH to include <comm_root>/Program/Java/Classes/java40.jar;<comm_root>/Program/Java/Classes/iiop10.jar
  • Applet: No special settings necessary.
To use CORBA and the Naming Service from Server-Side JavaScript:
Note: That the Flexi-Example mentioned in the below documentation, is incorrect.  The Flexi-Example incorrectly uses resolve.  Please use resolveURI.  See Accessing using Server-Side JavaScript for correct usage.

To use CORBA and the Naming Service from a separate machine:

NAMING SERVICE APIS

There are three types of APIs: Registering, Resolving, and Utilities.  Registering associates a CORBA Object with a URL.  Resolving converts a URL into a CORBA object reference.  Utilities are APIs that allow you to access CosNaming interfaces.  Different ways of registering and resolving are inter operable. 

Enterprise Server's Naming Service APIs*

LANGUAGE REGISTERING RESOLVING
Java register (doc) **,*** 
registerObject (doc) ** 
registerWAS (doc) **
resolve (doc) *** 
resolveURI (doc)
C++ registerObject (doc) ** 
registerWAS (doc) **
resolveURI (doc
resolveWAS (doc)
* putObject and putContext are Naming Service APIs for Internal Use Only and not mentioned in this TechNote.
** Port number is optional
*** Calls to register/resolve using Communicator and using Enterprise Server places Object References at different URL locations. See ES's register/resolve call and Communicator's register/resolve call for details.
 
LANGUAGE UTILITIES
Java getRootNaming 
NameFromString
 

Communicator's Naming Service APIs

LANGUAGE REGISTERING RESOLVING
Java register (doc) **, *** resolve (doc) **, ***
 

Enterprise Server : C++ : registerObject

WAIReturnType_t registerObject(const char *hostAndPort, const char *objectName, CORBA::Object_ptr obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.

MAPPING: A C++ registerObject call maps the obj's reference to:

    http://<hostAndPort>/NameService/<objectName>

EXAMPLE:

    ret = registerObject( "mikelee:80", "Howdy", obj );
     
      maps the obj to
       
    http://mikelee:80/NameService/Howdy

Enterprise Server : C++ : registerWAS

WAIBool registerWAS(const char *hostAndPort, const char *objectName, CORBA::Object_ptr obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.

MAPPING: A C++ registerWAS call maps the obj's reference to:

    http://<hostAndPort>/NameService/WAS/<objectName>

EXAMPLE:

    rc = registerWAS("mikelee:80", "Howdy", obj);
     
      maps the obj to
       
    http://mikelee:80/NameService/WAS/Howdy

Enterprise Server : C++ : resolveURI

WAIReturnType_t resolveURI(const char *host, int port, const char *uri, CORBA::Object_ptr& obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.

MAPPING:  A C++ resolveURI call maps the obj's reference to:

    http://<host>:<port>/<uri>

EXAMPLE:

    rc = resolveURI("mikelee", 80, "/NameService/Howdy", obj);
     
      resolves using
       
    http://mikelee:80/NameService/Howdy

Enterprise Server : C++ : resolveWAS

CORBA::Object_ptr resolveWAS(const char *objectName);

DESCRIPTION:

    Registers a CORBA Object to a URL.  This call automatically looks up the host.

MAPPING:  A C++ resolveWAS call maps the obj's reference to:

    http://<host>/NameService/WAS/<objectName>

EXAMPLE:

    obj = resolveWAS("Howdy");
     
      resolves using
       
    http://mikelee:80/NameService/WAS/Howdy

Enterprise Server : Java : register

public static void register(String url, org.omg.CORBA.Object obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.  This call automatically inserts "NameService" in between the host and the path/object name.  Calling register using the Enterprise Server's ORB is different than using Communicator's ORB.

MAPPING:  A Java register call using Enterprise Server's ORB maps the obj's reference to:

    http://<modified url>

EXAMPLE:

    obj = register("http://mikelee:80/Howdy");
     
      maps obj to
       
    http://mikelee:80/NameService/Howdy

Communicator : Java : register

public static void register(String url, org.omg.CORBA.Object obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.  This call uses an HTTP Put command to place the CORBA Object's reference at the specified URL.  Calling register using the Communicator's ORB is different than using Enterprise Server's ORB.

MAPPING:  A Java register call using Communicator's ORB maps the obj's reference to:

    http://<url>

EXAMPLE:

    obj = register("http://mikelee:80/NameService/Howdy");
     
      maps obj to
       
    http://mikelee:80/NameService/Howdy
     

Enterprise Server : Java : registerObject

public static boolean registerObject(String hostAndPort, String uri, org.omg.CORBA.Object obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.  Unlike the C++ call, "NameService" has to be manually inserted within the uri.

MAPPING:  A Java registerObject call maps the obj's reference to:

    http://<hostAndPort>/<uri>

EXAMPLE:

    obj = registerObject("mikelee:80", "/NameService/Howdy", obj);
     
      maps obj to
       
    http://mikelee:80/NameService/Howdy

Enterprise Server : Java : registerWAS

public static boolean registerWAS(String hostAndPort, String objectName, org.omg.CORBA.Object obj);

DESCRIPTION:

    Registers a CORBA Object to a URL.

MAPPING:  A Java registerWAS call maps the obj's reference to:

    http://<hostAndPort>/NameService/WAS/<objectName>

EXAMPLE:

    obj = registerWAS("mikelee:80", "Howdy", obj);
     
      maps obj to
       
    http://mikelee:80/NameService/WAS/Howdy

Enterprise Server : Java : resolve

public static org.omg.CORBA.Object resolve(String url);

DESCRIPTION:

    Resolves a CORBA Object reference from a URL.  This call automatically inserts "NameService" in between the host and the path/object name.  Calling resolve using the Enterprise Server's ORB is different than using Communicator's ORB.

MAPPING:  A Java resolve call maps the obj's reference to:

    http://<modified url>

EXAMPLE:

    obj = resolve("http://mikelee:80/Howdy");
     
      resolves using
       
    http://mikelee:80/NameService/Howdy

Communicator : Java : resolve

public static org.omg.CORBA.Object resolve(String url);

DESCRIPTION: Registers a CORBA Object to a URL.  Calling register using the Communicator's ORB is different than using Enterprise Server's ORB.
MAPPING:  A Java resolve call using Communicator's ORB maps the obj's reference to:

    http://<url>

EXAMPLE:

    obj = resolve("http://mikelee:80/NameService/Howdy");
     
      resolves using
       
    http://mikelee:80/NameService/Howdy

Enterprise Server : Java : resolveURI

public static org.omg.CORBA.Object resolveURI(String protocol, String host, int port, String uri);

DESCRIPTION:

    Registers a CORBA Object to a URL.

MAPPING: A Java resolveURI call maps the obj's reference to:

    <protocol>://<host>:<port>/<uri>

EXAMPLE 1:

    obj = resolveURI("http", "mikelee", 80, "/NameService/Howdy");
     
      resolves using
       
    http://mikelee:80/NameService/Howdy

EXAMPLE 2:

    obj = resolveURI("http", "mikelee", 80, "/NameService/WAS/Howdy");
     
      resolves using
       
    http://mikelee:80/NameService/WAS/Howdy

Enterprise Server : Java : getRootNaming

public static CosNaming.NamingContext getRootNaming(String host, int port);

DESCRIPTION:

    Gives access to CosNaming by returning a NamingContext.  See Using NamingContext for more details.

Enterprise Server : Java : NameFromString

public static CosNaming.NameHolder NameFromString(String s, String sepchar);

DESCRIPTION:

    Converts a string to CosNaming.NameHolder (NameHolder is equivalent to Name in CosNaming).  See Using NamingContext for more details.

ACCESSING USING JAVA: APPLICATION

DESCRIPTION:

MORE INFO:

PRE-REQ:

EXAMPLE 1: Registering using Enterprise Server's ORB

    package SendMsg;

    public class MsgService {
      static public void main( String[] args ) {
        //Instantiate Corba Implementation
        try {
            // Initialize ORB
            org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

            // Initialize BOA
            org.omg.CORBA.BOA boa = orb.BOA_init();

            // Create CORBA Object
            HelloImpl hi = new HelloImpl( "Howdy" );

            // Export newly created object to the ORB
            boa.obj_is_ready( hi );

            // Register object using web naming
            // Alternatively:
            //   netscape.WAI.Naming.register( "http://mikelee:80/Howdy", hi );
            // May be used.
            netscape.WAI.NameUtil.registerObject( "mikelee:80", "/NameService/Howdy", hi );
            System.out.println("Howdy: Ready for Service");
     
            boa.impl_is_ready( );
        }
        catch ( Exception e ) {
            System.err.println(e);
            e.printStackTrace();
        }
      }
    }

EXAMPLE 2:  Resolving using Enterprise Server's ORB

    package SendMsg;

    public class MsgClient {
      static public void main( String[] args ) {
        //Instantiate Corba Implementation
        try {
          // Initialize ORB
          org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

          String protocol = "http";
          String host = "mikelee";
          int port = 80;
          String uri = "/NameService/Howdy";
          // Resolve object
          // Alternatively:
          //   netscape.WAI.Naming.resolve( "http://mikelee:80/Howdy" );
          // May be used.
          org.omg.CORBA.Object o = netscape.WAI.NameUtil.resolveURI( protocol, host, port, uri );
          Hello hi = HelloHelper.narrow(o);
          System.out.println(hi.sayHello());
        }
        catch ( Exception e ) {
          System.err.println(e);
          e.printStackTrace();
        }
      }
    }

EXAMPLE 3: Registering using Communicator's ORB

    package SendMsg;

    public class MsgService {
      static public void main( String[] args ) {
        //Instantiate Corba Implementation
        try {
            // Initialize ORB
            org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

            // Initialize BOA
            org.omg.CORBA.BOA boa = orb.BOA_init();

            // Create CORBA Object
            HelloImpl hi = new HelloImpl( "Howdy" );

            // Export newly created object to the ORB
            boa.obj_is_ready( hi );

            // Register object using web naming
            String url = "http://mikelee/NameService/Howdy";
            netscape.WAI.Naming.register( url, hi );
            System.out.println(url + ": Ready for Service");
     
            boa.impl_is_ready( );
        }
        catch ( Exception e ) {
            System.err.println(e);
            e.printStackTrace();
        }
      }
    }

EXAMPLE 4:  Resolving using Communicator's ORB

    package SendMsg;

    public class MsgClient {
      static public void main( String[] args ) {
        //Instantiate Corba Implementation
        try {
          // Initialize ORB
          org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

          String url = "http://mikelee/NameService/Howdy";
          // Resolve object
          org.omg.CORBA.Object o =netscape.WAI.Naming.resolve( url );
          Hello hi = HelloHelper.narrow(o);
          System.out.println(hi.sayHello());
        }
        catch ( Exception e ) {
          System.err.println(e);
          e.printStackTrace();
        }
      }
    }


ACCESSING USING JAVA: APPLET

DESCRIPTION:

MORE INFO:

PRE-REQ:

EXAMPLE:  Registering

    package SendMsg;
    import java.applet.*;

    public class MsgClientApplet extends Applet {
      public void init( ) {
        //Instantiate Corba Implementation
        try {
          // Initialize ORB
          org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

          // Initialize BOA
          org.omg.CORBA.BOA boa = orb.BOA_init();

          // Create Hello Implementation Object
          HelloImpl hi = new HelloImpl( "Mike" );

          // Export newly created object to the ORB
          boa.obj_is_ready( hi );

          // Register object using web naming
          String url = "http://" + getCodeBase().getHost()
                     + ":" + getCodeBase().getPort()
                     + "/NameService/Howdy";
          netscape.WAI.Naming.register( url, hi );
          System.out.println( url + ": Ready for Service");
     
          boa.impl_is_ready( );
        }
        catch ( Exception e )
        {
          System.err.println(e);
          e.printStackTrace();
        }
      }
    }

EXAMPLE: Resolving

    package SendMsg;
    import java.applet.*;

    public class MsgClientApplet extends Applet{
      public void init( ) {
        //Instantiate Corba Implementation
        try {
            // Initialize ORB
            org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

            // Register object using web naming
            String url = "http://" + getCodeBase().getHost()
                     + ":" + getCodeBase().getPort()
                     + "/NameService/Howdy";
            org.omg.CORBA.Object o = netscape.WAI.Naming.resolve( url );
            Hello hi = HelloHelper.narrow(o);
            System.out.println(hi.sayHello());
        }
        catch ( Exception e ) {
            System.err.println(e);
            e.printStackTrace();
        }
      }
    }


ACCESSING USING C++

DESCRIPTION:

MORE INFO:

PRE-REQ:

EXAMPLE: Registering

    // MsgService.cpp
    #include "HelloImpl.cpp"
    #include <NameUtil.hpp>
    int main(int argc, char* const* argv) {
      try{
        // Initialize the ORB and the BOA.
        CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
        CORBA::BOA_var boa = orb->BOA_init(argc, argv);
        HelloImpl* hi = new HelloImpl();
        WAIReturnType_t rc;
        char *objectName = "Howdy";
        char *hostAndPort = "mikelee:80";
        boa->obj_is_ready(hi);
        rc = registerObject(hostAndPort, objectName, hi);
        cerr << objectName << ": Ready for Service" << endl;
        boa->impl_is_ready();
        return(0);
      }
      catch (CORBA::SystemException& e)
      {
        cerr << e << endl;
        return(1);
      }
      catch (...)
      {
        cerr << "Unknown exception" << endl;
        return(1);
      }
      return(0);
    }

EXAMPLE: Resolving

    // MsgClient.cpp
    #include "SendMsg_c.hpp"
    #include <NameUtil.hpp>

    int main(int argc, char* const* argv) {
      try {
        // Initialize the ORB.
        CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
        SendMsg::Hello_var hi;
        // Find a reference to the Hello service.
        WAIReturnType_t ret;
        CORBA::Object_ptr p;
        char* host = "mikelee";
        int port = 80;
        char* objName = "/NameService/Howdy";
        ret = resolveURI(host, port, objName, p);
        // Narrow the reference.
        hi = SendMsg::Hello::_narrow(p);
        // Call a method provided by the service.
        cout << hi->sayHello() << endl;
      }
      catch (CORBA::SystemException& e)
      {
        cerr << e << endl;
        return(1);
      }
      catch (...)
      {
        cerr << "Unknown exception" << endl;
        return(1);
      }
      return(0);
    }


ACCESSING USING CLIENT-SIDE JAVASCRIPT

DESCRIPTION:

PRE-REQ:

    None

EXAMPLE: Resolving

    <SCRIPT>
      // Initialize ORB
      var orb = Packages.org.omg.CORBA.ORB.init();
      var url = "http://mikelee/NameService/Howdy";
      var o = Packages.netscape.WAI.Naming.resolve( url );
      var hi = Packages.SendMsg.HelloHelper.narrow( o );
      var str = hi.sayHello();
      document.write( "<H1> + str + "</H1>");
    </SCRIPT>

ACCESSING USING SERVER-SIDE JAVASCRIPT

DESCRIPTION:

MORE INFO:

PRE-REQ:

EXAMPLE: Resolving

    <SERVER>
      // No need to initialize the orb. ORB already initialized by Enterprise Server.

      // By default, assume name service is running on this server.
      var protocol = "http";
      var host = server.hostname;
      var port = 80;
      var uri = "/NameService/Howdy";
      var o = netscape.WAI.NameUtil.resolveURI("http", "mikelee", 80, "/NameService/Howdy");
      project.hi = Packages.SendMsg.HelloHelper.narrow(o);
      var str = project.hello.sayHello();
      write( "<H1>" + str + "</H1>" );
    </SERVER>


ACCESSING USING VISUAL JAVASCRIPT

This topic is covered by Visual JavaScript Developer's Guide and the Component Developer's Guide.  Specifically, see Component Developer's Guide's chapter on Using CORBA Components.  Visual JavaScript uses the client URL mapping of the Communicator's Naming APIs.


USING NAMINGCONTEXT

NamingContext allows access to CosNaming.  A detailed discussion of NamingContext is out of scope for this TechNote.  For detailed information please see the book by Andreas Vogel and Keith Duddy, Java Programming with CORBA.

Q. Why mention NamingContext at all?
A. NamingContext allows you to get full access to CosNaming.  However for this TechNote we will focus on the functionality that allows you to know if a CORBA server is:

  • not registered (not started)
  • started but not responding

Currently when you start a CORBA Object, let's call it "Howdy," and register it with the Naming Service, this rebinds the Object reference with the url.  Even if we stop the server, the Naming Service still has "Howdy" registered.  When a client attempts to access "Howdy" the exception that is thrown merely states that the connection was refused because of org.omg.CORBA.COMM_FAILURE.  The client has no idea if the server was stopped or there was an error condition within the network.

To address this, we can "unbind" a CORBA server during it's shutdown.  If we unbind "Howdy" during shutdown of the "Howdy" server, we can catch the following exceptions attempting to access the "Howdy" server:

  • org.omg.CORBA.INV_OBJREF:  Server not registered (not started) at the requested URL:
  • org.omg.CORBA.COMM_FAILURE:  Server registered, but some other error condition (server crashed, etc):

EXAMPLE 1: Shutdown

    ...
    // "Howdy" already registered within the Naming Service
    public void shutdown {
      //Instantiate Corba Implementation
      try {
        // Assumption: ORB already initialize ORB
     
        // Retrieve NamingContext of web server
        CosNaming.NamingContext nc = netscape.WAI.NameUtil.getRootNaming("mikelee", 80);

        // Create NameHolder with "Howdy
        CosNaming.NameComponent[] howdyName;
        howdyName = NameUtil.NameFromString("Howdy", "/").value;

            // Unregister "Howdy" from NameService
        nc.unbind( howdyName );
      catch ( Exception e ) {
            System.err.println(e);
            e.printStackTrace();
      }
    }
    ...

EXAMPLE 2: Resolving, with more granular exception handling.

    package SendMsg;

    public class MsgClient {
      static public void main( String[] args ) {
        //Instantiate Corba Implementation
        try {
            // Initialize ORB
            org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init();

            // Register object using web naming
            org.omg.CORBA.Object o = netscape.WAI.Naming.resolve( "http://mikelee/Howdy" );
            Hello hi = (Hello)HelloHelper.narrow(o);
            System.out.println(hi.sayHello());
        }
        catch ( org.omg.CORBA.INV_OBJREF e ) {
            System.err.println("Server not started");
            System.err.println(e);
            e.printStackTrace();
        }
        catch ( org.omg.CORBA.COMM_FAILURE e ) {
            System.err.println("Cannot reach server.  Server went down or communication failure.");
            System.err.println(e);
            e.printStackTrace();
        }
        catch ( Exception e ) {
            System.err.println("Unknown exception.");
            System.err.println(e);
            e.printStackTrace();
        }
      }
    }
     

TN-CORB-01-9801


Related Readings:


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

© 2001 Sun Microsystems, Inc.