Chapter 13 Creating CORBA-Compatible Java Clients


Using client-side naming interfaces

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.

Instantiating proxies with the CosNaming API

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:

Step

What it does

Detailed explanation

1

Configure ORB properties, including the ORB runtime driver class and the Jaguar naming server URL, then initialize the ORB runtime.

"Configuring and initializing the ORB runtime"

2

Instantiate the CORBA CosNaming naming service and obtain the initial naming context.

"Obtaining an initial naming context"

3

Resolve component names to proxy objects and narrow them to the stub interface.

"Instantiating proxy objects for Jaguar components"

Initializing the ORB

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

where

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/

Obtaining an initial naming context

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.

Note   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 ...
}

Instantiating proxy objects for Jaguar components

Proxy objects are instantiated as follows:

  1. Create a NameComponent array that names the component. Component names are composed as follows:
    server-context/package/component

    where
  2. Call the NamingContext.resolve method. It returns a factory object for the component. You can use the factory to create proxy objects.
  3. Narrow the CORBA Object reference to a SessionManager::Factory instance.
  4. Call the factory's create method and narrow the return value by calling the narrow method in the generated helper class for the interface. The create method requires a username and password to authenticate the end user.

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 ...
}
}

Instantiating proxies with JNDI

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:

Step

What it does

Detailed explanation

1

Configure JNDI properties and create the initial naming context.

"Creating the JNDI initial naming context"

2

Call the lookup method to resolve component names to a proxy object, then narrow the object to an interface that is supported by the component.

"Calling the JNDI lookup method"

Creating the JNDI initial naming context

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:

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.

Calling the JNDI lookup method

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

where

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.