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.
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*
* 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.
Communicator's Naming Service APIs
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 );
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);
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);
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");
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:
EXAMPLE:
obj = register("http://mikelee:80/Howdy");
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:
EXAMPLE:
obj = register("http://mikelee:80/NameService/Howdy");
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);
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);
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:
EXAMPLE:
obj = resolve("http://mikelee:80/Howdy");
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:
EXAMPLE:
obj = resolve("http://mikelee:80/NameService/Howdy");
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");
http://mikelee:80/NameService/Howdy
EXAMPLE 2:
obj = resolveURI("http", "mikelee", 80, "/NameService/WAS/Howdy");
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:
A Java application that is run outside of the browser may use either
the Communicator's ORB or the Enterprise Server's ORB.
Communicator ORB:
Enterprise Server ORB:
MORE INFO:
PRE-REQ:
Communicator ORB:
Enterprise Server ORB:
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:
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