JNDI/COS Naming Service Provider

# COS Naming Service Provider for the
Java Naming and Directory InterfaceTM (JNDI)

Please send feedback to jndi@java.sun.com

Table of Contents

- Introduction
- Conformance
- Environment Properties
- ORB Initialization
- Root Naming Context Initialization
- Names and URLs
- API Mapping
- Converting CORBA Programs to use JNDI
- Security Considerations

## Introduction

The Common Object Services (COS) Name Server is the name server for storing Common Object Request Broker Architecture (CORBA) object references. It can be accessed from CORBA applications by using the COS Naming package (org.omg.CORBA.CosNaming).

The JNDI/COS naming service provider implements the `javax.naming.Context` interface on top of the COS Naming package in order to allow applications to use JNDI to access the COS Name Server. JNDI can also be used to access other naming and directory services, in addition to the COS Name Server, thereby offering the CORBA application one interface for accessing different naming and directory services.

This document describes the features of the COS naming service provider and contains details of how JNDI is mapped to the COS naming package.

## Conformance

The COS naming service provider for JNDI uses JavaTM IDL, the Java programming language mapping to the industry standard Object Management Group Interface Definition Language (OMG IDL). In particular, it uses the COS Naming Service.

The complete specification for COS Naming can be obtained from OMG.

The syntax of names conforms to the Interoperable Naming Service (INS) specification (99-12-03), with backward compatibility support for the previous version of INS, OMG TC Document orbos/98-10-11. This is described in Names and URLs.

## Environment Properties

The following JNDI environment properties are relevant for the COS naming service provider. See the JNDI documentation for a description of how properties are initialized using the environment properties, system properties, applet parameters, and resource files.

    java.naming.factory.initial

> This property is used to select the COS naming service provider; it's not actually used by the provider itself. It specifies the class name of the initial context factory for the provider.

> For example:

> >     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactory");

> This property must be set if you are using the COS naming service as the initial context. The only exception is if you supply only URLs to the initial context, in which case, you don't need to specify this property. See Names and URLs for details.

    java.naming.provider.url

> This property is used to configure the root naming context and/or the Object Request Broker (ORB). Its value is the string representation of a URL.

> If this property is not specified, then the ORB is initialized using the `java.naming.corba.orb` property, the `java.naming.applet` property, or other ORB initialization properties. The root naming context is obtained by invoking

> >     orb.resolve_initial_references("NameService");

> If the URL scheme is one of "IOR", "corbaname", or "corbaloc", as specified in the INS specification (99-12-03), then the root naming context is that named by the URL. The ORB is initialized using the `java.naming.corba.orb` property, the `java.naming.applet` property, or other ORB initialization properties.

> If the URL scheme is either "iiop" or "iiopname", then the host and port fields of the URL are used to initialize the ORB. An "iiopname" URL must conform to the now obsolete INS specification (98-10-11). It has the form:

> >     iiopname://[<addr_list>][/<cosnaming_name>]

> The "iiop" URL scheme is supported for backward compatibility with an older version of the INS specification. It has the form:

> >     iiop://[<host>[:<port>]][/<cosnaming_name>]

> For both "iiop" and "iiopname" URLs, if `<host>` is not specified, then it defaults to "localhost" for an application and the applet's host for an applet. If `<port>` is not specified, then it defaults to 9999 for "iiopname", and 900 for "iiop". The root naming context is obtained by invoking the following method on the ORB:

> >     orb.resolve_initial_references("NameService");

> If `<cosnaming_name>` is nonempty, then the root naming context is the naming context named by `cosnaming_name`.

> If the URL scheme is not one of "iiop", "iiopname", "IOR", "corbaname", or "corbaloc", then the URL must name a location that contains the stringified IOR of the root naming context. For example, if the property contains `"file:/nsdir/ior"`, then the file `/nsdir/ior` must contain a stringified IOR. The URL scheme can be any for which there is a corresponding URL protocol handler ( `java.net.URLStreamHandler`). See the `java.net.URL` class for details. The stringified IOR is read from the data stream corresponding to the URL by using a character encoding of ISO Latin-1. The stringified IOR is the first line in the stream that contains the prefix "IOR:". For example, if the URL scheme is "http", then the headers in the stream are skipped and the first line that contains the prefix "IOR:" is returned as the IOR.

> When the property specifies a stringified IOR or the location of one, the root naming context is that named by the the stringified IOR. The ORB is initialized using the `java.naming.corba.orb` property, the `java.naming.applet` property, or other ORB initialization properties.

    java.naming.corba.orb

> This property specifies the ORB that the program is using. When the JNDI COS naming service provider needs to use an ORB, for example, to look up the "NameService" initial reference or to turn a stringified IOR into an object reference, it will use this ORB.

> In an application you can set this property as follows:

> >     ORB orb = ORB.init(args, null);
> >     Hashtable env = new Hashtable(5, 0.75f);
> >     env.put("java.naming.corba.orb", orb);
> >     ...

> In an applet, you can set it as follows:

> >     public class MyApplet extends Applet {

> >         public someInitMethod() {
> >             ORB orb = ORB.init(this, null);
> >             Hashtable env = new Hashtable(5, 0.75f);
> >             env.put("java.naming.corba.orb", orb);
> >             ...
> >         }
> >     ...
> >     }

> If this property is not set, then the `java.naming.provider.url` property, the `java.naming.applet` property, or the ORB initialization properties are used to initialize the ORB.

    java.naming.applet

> This property specifies the applet that the program is using. It is used to initialize the ORB to be used by the COS naming service provider. Its parameters are used for setting JNDI-related properties; see the JNDI documentation for details.

> >     public class MyApplet extends Applet {

> >         public someInitMethod() {
> >             Hashtable env = new Hashtable(5, 0.75f);
> >             env.put("java.naming.applet", this);
> >             ...
> >         }
> >     ...
> >     }

    java.naming.factory.state

> A colon-separated list of the fully qualified class names of state factory classes used to get an object's state for storing given the object itself. You can use this mechanism to transform an object into forms that can be stored into a COS name server. The COS name server supports storing CORBA objects.

> A state factory that transforms a `java.rmi.Remote` into a CORBA object is supplied by default. This factory is useful for applications that use RMI-IIOP. You can supply other factories to affect the transformation of other objects into CORBA objects for storing. See `javax.naming.spi.NamingManager.getStateToBind()` for details.

    java.naming.factory.object

> A colon-separated list of the fully qualified class names of object factory classes for transforming a CORBA object. You can use this mechanism to transform an object into forms expected by the application. For example, a specialized object factory could do the appropriate narrowing to return an object of the expected type. See `javax.naming.spi.NamingManager.getObjectInstance()` for details.

    java.naming.batchsize

> Specifies the batch size to use in `CosNaming::BindingIterator.next_n` when getting the results of a `list()`/`listBindings()`. The default is "100."

> For example, the following sets the batch size to be 24.

> >     env.put(Context.BATCHSIZE, "24");

ORB initialization properties

> You can specify CORBA related properties such as those with the "`org.omg.CORBA`." prefix as properties. Properties of type `String` are used to initialize the ORB.

## ORB Initialization

The properties that affect which ORB is used and how the ORB is initialized are:

-     java.naming.corba.orb

-     java.naming.applet

-     java.naming.provider.url

- `org.omg.CORBA.*` and other ORB-specific properties of type `String`

The following algorithm is used to determine which ORB is used:

1. If `java.naming.corba.orb` has been set, then its value (an ORB) is used.

2. Otherwise, the provider will internally initialize and use an ORB as follows:

     a) Any `org.omg.CORBA.*` properties and properties of type `String` are extracted and used as part of the `Properties` argument to the `ORB.init()` method. You can use this mechanism to specify, for example, the ORB implementation or host to use.

     b) If `java.naming.provider.url` has been set and it contains a URL of scheme "iiop" or "iiopname", then the host and port number specified in the URL are used as part of the `Properties` argument to the `ORB.init()` method, overriding any `org.omg.CORBA.ORBInitialHost` and `org.omg.CORBA.ORBInitialPort` properties set up in (a).

     c) The `Properties` instance constructed in (a) and (b) are passed to `ORB.init()` along with the `Applet` instance in `java.naming.applet` property, or an empty `String[]` if `java.naming.applet` was not supplied.

If the properties employed in steps (a), (b) and (c) contain no relevant information for initializing the ORB, then the Java IDL implementation's defaults are used. Typically that means port 900 on the local host for an application, and port 900 on the applet host for an applet are used. Note that when the ORB is initialized using `ORB.init()`, its arguments are checked in the following order: (from `org.omg.CORBA.ORB` javadoc)

1. Check in `Applet` parameter or application string array, if any
2. Check in properties parameter, if any
3. Check in the `System` properties (currently applications only)
4. Fall back on a hardcoded default behavior (use the Java IDL implementation)

## Root Naming Context Initialization

The root naming context is initialized either using the `java.naming.provider.url` property or by a `resolve_initial_references()` call on the ORB. If the `java.naming.provider.url` property is set but contains neither an "iiop" or "iiopname" URL, then it is assumed to contain a stringified IOR, a "corbaname" or "corbaloc" URL of an IOR, or a URL containing the location of a stringified IOR. The IOR is used to obtain the root naming context and must be that of a CORBA object of type `CosNaming::NamingContext`.

If the `java.naming.provider.url` has not been set, then the root naming context is obtained by invoking the following method on the ORB:

            orb.resolve_initial_references("NameService");

## Names and URLs

`String` Names

`String` names accepted by the `java.naming.Context` methods are JNDI composite names in which each component is the stringified form of a `CosNaming::NameComponent`.

A `CosNaming::Name` contains a sequence of `CosNaming::NameComponent`. The stringified form of a component is the concatenation of the component's id, the kind separator character ('.'), and the component's kind. The occurrence of any meta characters ('.', '/', or '\') in either the id or kind is escaped using the escape character ('\'). The stringified form of a `CosNaming::Name` is defined in Section 3.5 of the INS specification (99-12-03).

The JNDI composite name syntax is very similar to, but not identical to, the INS syntax. There are minor differences with respect to the treatment of escape and quote characters. If you want to use names with the precise INS syntax, then you should use the overloads that accept a `Name` argument instead of a `String` argument. The `Name` argument should be a value returned by `nameParser.parse()`, where `nameParser` is a value obtained from the COS naming service provider. See the Name Parsing section.

URL String Names

The URL form of a `CosNaming::Name` is defined in the INS specification.

> `corbaname:<corbaloc_obj>["#" <cosnaming_name>]`

where `<corbaloc_obj>` is

> `<corbaloc_obj> = <obj_addr_list> ["/" <key_string>]`

and `<obj_addr_list>` is a list of addresses as defined in a "corbaloc" URL and `<key_string>` is a key string as defined in a "corbaloc" URL. `<cosnaming_name>` is the stringified form of an INS name (see Name Parsing).

For backward compatibility with older versions of the INS, the following URL schemes are also supported.

> `iiopname://[<addr_list>][/<cosnaming_name>]`

where `<addr_list>` specifies a list of host/port pairs. If `<port>` is not specified, then it defaults to 9999. `<cosnaming_name>` is the stringified form of an INS name.

> `iiop://<host>[:<port>][/<cosnaming_name>]`

If `<port>` is not supplied, then it defaults to 900. `<cosnaming_name>` is the stringified form of an INS name.

When you supply an "iiop" or "iiopname" URL to the initial context in this way, the ORB supplied to the initial context is used if its `string_to_object()` method supports the 99-12-03 INS specification. Otherwise, the ORB is ignored and the server and port designations in the URL are used to create an ORB. The value of the `java.naming.factory.initial` property is ignored for the purposes of resolving the URL.

Note that this rule is not used when you supply a "corbaname" URL to the initial context. For a "corbaname" URL, the ORB supplied to the initial context is used because the ORB is needed to resolve the "corbaname" URL. Name Objects

The `Name` argument to a `Context` method is treated as a sequence of strings, each representing a stringified `CosNaming::NameComponent`.

Name Parsing

The COS naming service provider supports names in the syntax specified in the INS specification. In short, the syntax is that components are left-to-right slash ('/') separated and case-sensitive. The id and kind of each component are separated by the period character ('.').

Here is a code fragment that uses the name parser from the COS naming service provider to eventually do a lookup using an INS name.

>     String insName = ...;
>     InitialContext ctx = new InitialContext(env);   // env contains init properties
>     NameParser parser = ctx.getNameParser("");      // parser for INS names
>     Name name = parser.parse(insName);              // get parsed INS name
>     Object obj = ctx.lookup(name);                  // do lookup

## API Mapping

The COS name server supports only naming operations. The COS naming service provider maps the `javax.naming.Context` methods to use the appropriate COS Naming calls.

    addToEnvironment()

> Records change to environment property but does not reinitialize ORB.

    bind()

> Binds an object to the specified name.

> If the object being bound is an `org.omg.CosNaming.NamingContext`, then `CosNaming::NamingContext.bind_context` is used. If it is an `org.omg.CORBA.Object`, then `CosNaming::NamingContext.bind` is used. The binding of any other type of object is not supported unless the object can be converted into an `org.omg.CORBA.Object` using the state factory mechanism described next.

> Before the bind is performed on the naming server, the COS naming service provider uses `javax.naming.spi.NamingManager.getStateToBind()` to allow the object to be transformed into a `org.omg.CORBA.Object`. The `getStateToBind()` method uses the state factories available to the COS naming service provider. If the state factory accepts a `java.rmi.Remote` object, then it is responsible for obtaining the object's RMI-IIOP stub and connecting it to the ORB associated with the context. The connected stub is the object that will be bound in the naming server.

> By default, the COS naming service provider supplies and uses a state factory that transforms an object implementing the `java.rmi.Remote` interface to an `org.omg.CORBA.Object` following the requirements described above. This factory uses the utilities in the `javax.rmi.CORBA` package. You can supply additional state factories to transform objects into CORBA objects.

    close()

> Releases any internal data structures used.

    composeName()

> Concatenates the supplied name to the prefix.

    createSubcontext()

> Uses `CosNaming::NamingContext.bind_new_context` to create and bind a new context.

    destroySubcontext()

> Uses `CosNaming::NamingContext.destroy` to destroy the named context. Then uses `CosNaming::NamingContext.unbind` to remove the binding.

    getEnvironment()

> Returns the environment of this context.

    getNameInNamespace()

> Returns the INS name of this context relative to the root of the Cos Naming namespace.

    getNameParser()

> Returns a name parser for parsing INS names.

    lookup()
    lookupLink()

> Uses `CosNaming::NamingContext.resolve` to lookup the name. It returns a CORBA object reference except when the reference is that of a `CosNaming::NamingContext`, in which case a `Context` object is returned instead. `NamingManager.getObjectInstance()` is called before the object is returned in case the application or user has supplied object factories.

    list()
    listBindings()

> Uses `CosNaming::NamingContext.resolve` to get the object reference for the context, and then uses `CosNaming::BindingIterator` and helper classes to iterate through the context. The objects bound to the names are obtained by calling `CosNaming::NamingContext.resolve` on them. `NamingManager.getObjectInstance()` is called before the object is returned in case the application or user has supplied object factories.

    removeFromEnvironment()

> Removes the specified property from the environment but does not otherwise update the context.

    rebind()

> If the object being bound is an `org.omg.CosNaming.NamingContext`, then `CosNaming::NamingContext.rebind_context` is used. If it is an `org.omg.CORBA.Object`, then `CosNaming::NamingContext.rebind` is used. See `bind()` for details on the use of state factories to transform the argument into an `org.omg.CORBA.Object`.

    rename()

> This method is implemented using `bind()` followed by `unbind()`. It is not atomic.

    unbind()

> Uses `CosNaming::NamingContext.unbind` to unbind the object.

## Converting CORBA Programs to use JNDI

This section explains how to modify your Java IDL program to use JNDI. The explanation uses the Java IDL sample programs `helloClient.java` and `helloServer.java`.

1. Generate the stubs from the IDL file.

   >     # idltojava -fclient -fserver hello.idl

   This creates the client (`helloClient.java`) and server (`helloServer.java`) skeletons, and a directory containing common code (e.g. `HelloApp/*.java`).

2. Fill in the code for the client and server programs.

3. Modify (or copy the client and server files) to use JNDI instead of COS Naming directly.

   - Replace the import to use `javax.naming.*;`

     > Delete:

     >     import org.omg.CosNaming.*;
     >     import org.omg.CosNaming.NamingContextPackage.*;

     > Add:

     >     import javax.naming.*;

   - Replace how you get the initial reference to "NameService" with `InitialContext`, supplying the initial context the ORB being used by the current application.

     > Delete:

     >     org.omg.CORBA.Object objRef =
     >        orb.resolve_initial_references("NameService");
     >     NamingContext ncRef = NamingContextHelper.narrow(objRef);

     > Add:

     >     Hashtable env = new Hashtable(5, 0.75f);
     >     env.put("java.naming.corba.orb", orb);
     >     Context ic = new InitialContext(env);

   - Replace the call to `resolve()` to use `lookup()`.

     > Delete:

     >     // resolve the Object Reference in Naming
     >     NameComponent nc = new NameComponent("Hello", "");
     >     NameComponent path[] = {nc};
     >     hello helloRef = helloHelper.narrow(ncRef.resolve(path));

     > Add:

     >     // resolve the Object Reference using JNDI
     >     hello helloRef =
     >     helloHelper.narrow((org.omg.CORBA.Object)ic.lookup("Hello"));

## Security Considerations

When a security manager has been installed, you must grant to the application using JNDI and the COS naming service provider the following permissions:

    permission java.net.SocketPermission "host[:port]", "connect";

> For each host/port identified in the `java.naming.factory.initial` property, in URL string names supplied to context methods, in ORB initialization parameters and properties, and in object references.

Copyright © 1999-2001 Sun Microsystems, Inc., All Rights Reserved.