Chapter 13 Creating CORBA-Compatible Java Clients
Jaguar allows you to use the CosNaming and JNDI interfaces to instantiate proxies in your client applications. These techniques of instantiating proxies are not recommended, because:
You do not need to use the CosNaming or JNDI API in clients to realize the benefits incurred by using logical component names. When you use the technique described in "Instantiating proxy instances", the Jaguar server uses the CosNaming API to resolve component names in the implementation of the Session.lookup and Session.create methods.
The CORBA naming service resolves component names to server-side objects. On the client side, the naming service is represented by an object that implements the CosNaming IDL interface.
The steps for resolving objects with CosNaming are as follows:
Before you can call any other ORB methods, you must configure ORB properties and call the org.omg.CORBA.ORB.init method. "Configuring and initializing the ORB runtime" describes how to do this. In addtion, you must set the the com.sybase.CORBA.NameServiceURL property.
com.sybase.CORBA.NameServiceURL specifies the list of URLs with the host and port number for IIOP connectivity to the Jaguar name servers for your application. Each URL takes the the form:
protocol://hostname:iiop-port/initial-context
iiop
or iiops
.
Use iiops
if connecting to
a secure IIOP port, and iiop
otherwise.
localhost
.
USA/Sybase/
,
all names that you resolve with the context are assumed to be relative
to this location in the name hierarchy. When specifying the initial
context, the trailing slash is optional; it is added automatically
if you do not specify an initial context that ends with a slash.
If your application uses a cluster of Jaguar servers, the cluster may use multiple name servers. In this case, specify the URLs for each name server in a list separated by semicolons and no white space. Include the cluster's initial naming context only with the last URL. For example:
iiop://host1:9000;iiop://host2:9000/USA/Sybase/
If you do not set the com.sybase.CORBA.NameServiceURL, property, the default is assumed. Different defaults are used depending whether your client is a Java application or a Java applet. The applet default is:
iiop://download-host:9000/
which indicates that the Jaguar ORB expects the name server to be available at port 9000 on the host from which the applet was downloaded, and that the initial naming context is the root context (/).
The default for applications is:
iiop://localhost:9000/
After initializing the ORB, call the ORB.resolve_initial_references method to obtain the initial naming context. The naming context is an object that implements the CosNaming::NamingContext IDL interface; it is used to resolve Jaguar component and service names to server-side objects.
Obtaining the initial context The example below shows how the initial naming context is retrieved:
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
public class myApplet extends Applet {
... deleted ORB initialization code ...
NamingContext nc = null;
org.omg.CORBA.Object objRef = null;
try {
objRef = orb.resolve_initial_references(
"NameService");
nc = NamingContextHelper.narrow(objRef);
} catch (org.omg.CORBA.ORBPackage.InvalidName ine) {
nc = null;
}
if (nc == null) {
System.out.println("Error: Could not "
+ "instantiate CORBA naming context.");
return;
}
Introduction to CosNaming name resolution The initial NamingContext will have the name context that was specified in the com.sybase.CORBA.NameServiceURL ORB initialization property. Your client program invokes the NamingContext::resolve operation to obtain an instance of the Jaguar authentication service as well as component instances.
Jaguar's CosNaming implementation currently lacks support for the BindingIterator interface, which is used to browse the name hierarchy.
The NamingContext::resolve operation takes a CosNaming::Name parameter, which is a sequence of CosNaming::NameComponent structures. The Java definitions of these types and the NamingContext::resolve operation follow:
package org.omg.CosNaming;
class NameComponent {
public String id; // Represents a node in a name
public String kind; // Unused, can contain comment info
// Construct a NameComponent instance with the
// specified initial values for id and kind fields
public NameComponent(String id, String kind);
}
interface NamingContext {
... other methods not shown ...
public org.omg.CORBA.Object resolve
(NameComponent[] n)
throws
org.omg.CosNaming.NamingContextPackage.NotFound,
org.omg.CosNaming.NamingContextPackage.CannotProceed,
org.omg.CosNaming.NamingContextPackage.InvalidName;
}
In Java, a name is represented by an array of NameComponent instances, with the id field of each instance set to a node of the name. For example, the name
USA/Sybase/Jaguar/TestPackage/TestComponent
can be represented by the array theName which is created in this code fragment:
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
public class myApplet extends Applet {
NamingContext nc;
... deleted code that retrieves initial NamingContext ...
NameComponent theName[] = {
new NameComponent("USA", ""),
new NameComponent("Sybase", ""),
new NameComponent("Jaguar", ""),
new NameComponent("TestPackage", ""),
new NameComponent("TestComponent", "")
} ;
To simplify your source code, the Jaguar naming service allows you to specify multiple nodes of a name in one NameComponent instance, using a forward slash (/) to separate nodes. The name from the example above can be represented in a one-element array as shown below:
NameComponent theName[] = {
new NameComponent(
"USA/Sybase/Jaguar/TestPackage/TestComponent", "")
};
NamingContext::resolve resolves a name to an object; this method either returns an org.omg.CORBA.Object instance or throws one of the exceptions described below:
The code fragment below illustrates a typical call with exception handling:
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
public class myApplet extends Applet {
try {
NamingContext nc;
... deleted code that retrieves initial NamingContext ...
NameComponent theName[] = {
new NameComponent(
"USA/Sybase/Jaguar/TestPackage/TestComponent", ""));
org.omg.CORBA.Object obj = nc.resolve(theName);
... deleted code that narrows the object to a supported interface ...
} catch (NotFoundException nfe) {
... report the error ...
} catch (InvalidName ine ) {
... report the error ...
} catch (CannotProceed cpe) {
... report the error ...
}
Proxy objects are instantiated as follows:
server-context/package/component
The example below instantiates a component MyComponent, installed in package MyPackage, hosted on a server with initial context USA/Sybase/Jaguar. The username and password are Guest and GuestPassword, respectively. The component implements the IDL interface MyPackage::MyInterface, and the code narrows the proxy object to that interface.
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.CosNamingPackage.*;
import SessionManager.*;
public class myApplet extends Applet {
NamingContext nc;
... deleted code that created initial naming context
...
// Create a NameComponent array for
// USA/Sybase/Jaguar/MyPackage/MyComponent
//
NameComponent compName[] = {
new NameComponent("USA", ""),
new NameComponent("Sybase", ""),
new NameComponent("Jaguar", ""),
new NameComponent("MyPackage", ""),
new NameComponent("MyComponent", "")
try {
// Resolve the name to obtain the proxy object
org.omg.CORBA.Object obj = nc.resolve(compName);
// Narrow to a factory instance
Factory compFactory = FactoryHelper.narrow(obj);
// Get the proxy object and narrow it to MyInterface.
obj = compFactory.create("Guest", "GuestPassword");
MyPackage.MyInterface comp =
MyPackage.MyInterfaceHelper.narrow(obj);
}
catch (NotFoundException nfe) {
... report the error ...
}
catch (CannotProceed cpe) {
... report the error ...
}
catch (InvalidName ine) {
... report the error ...
}
}
Java Naming and Directory Interface (JNDI) is a Java standard extension that defines interfaces for users of naming and directory services. The standard also defines driver interfaces for provider classes, allowing integration with a variety of name and directory server architectures. You can read more about JNDI at the JavaSoft Web site, http://www.javasoft.com/.
Jaguar includes a JNDI provider that client programs use to resolve component names to proxy objects. The steps below summarize the procedure:
The core interface used for JNDI name resolution is javax.naming.Context. In order to instantiate this interface, you must first initialize a java.util.Properties object. The Jaguar JNDI provider requires the following properties:
com.sybase.jaguar.jndi.CosNaming.JaguarInitial
ContextFactory
iiop://hostname:iiop-port/initial-context
localhost
.
iiop://localhost:9000/
After initializing the Properties instance, use it to construct a javax.naming.InitialContext instance, as shown in the example below:
// Initialize a Properties object for the
// initial JNDI context that interacts with
// the Jaguar name server
//
Properties envJNDI = new Properties();
// Class name of the factory for Jaguar JNDI contexts
envJNDI.put(
"java.naming.factory.initial",
"com.sybase.jaguar.jndi.CosNaming.JaguarInitialContextFactory"
);
// Authentication properties:
// SECURITY_PRINCIPAL is the Jaguar user name,
// SECURITY_CREDENTIALS is the password
//
envJNDI.put(javax.naming.Context.SECURITY_PRINCIPAL, "Guest");
envJNDI.put(javax.naming.Context.SECURITY_CREDENTIALS,
"GuestPassword");
// PROVIDER_URL specifies the IIOP address of the
// Jaguar server that is the name service for the application,
// plus the initial naming context. The setting used in
// this example works with the default configuration.
// If you have configured a different server as the name
// server for your application, change the PROVIDER_URL
// to connect to that server. If you have defined a
// naming context for your server, append it to the
// PROVIDER_URL value.
//
// Note that the PROVIDER_URL uses localhost as a default
// host name rather than the applet download host.
// Thus we must specify the download host explicitly.
//
envJNDI.put(javax.naming.Context.PROVIDER_URL,
"iiop://"
+ this.getCodeBase().getHost()
+":9000/");
// Now allocate the initial context. Internally,
// this call initializes the Jaguar CORBA ORB
// and creates a Jaguar SessionManager::Session
// instance. Consequently, those steps aren't
// necessary in a client that instantiates objects
// using JNDI.
//
javax.naming.Context initctx = new InitialContext(envJNDI);
You can instantiate multiple naming contexts with different properties, by initializing different java.util.Properties with different settings, then using them to construct separate InitialContext instances.
Call the lookup method on the initial context to instantiate a proxy object for the component. lookup takes a component name (represented by a String or by a javax.naming.Name instance). Names for Jaguar components are composed as follows:
server-context/package/component
lookup returns a java.lang.Object which must be narrowed to an instance of an interface that the component supports. Narrow the proxy object by calling the narrow method in the generated helper class for the interface.
The example below instantiates a component MyComponent, installed in package MyPackage, hosted on a server with root context USA/Sybase/Jaguar. The component implements the IDL interface MyPackage::MyInterface, and the code narrows the proxy object to that interface.
try {
javax.naming.Context initctx = new InitialContext(envJNDI);
_comp = MyPackage.MyInterfaceHelper.narrow(
(org.omg.CORBA.Object) initctx.lookup(
"MyPackage/MyComponent"));
} catch (NamingException ne)
{
System.out.println(
"Error while instantiating component: " + ne.toString());
ne.printStackTrace();
}
Copyright © 2000 Sybase, Inc. All rights reserved. |