Skip Headers

Oracle® Containers for J2EE Services Guide 10g Release 3 (10.1.3) B14427-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 2 Oracle JNDI

This chapter describes the Java Naming and Directory Interface (JNDI) service as implemented by Oracle Containers for J2EE (OC4J). The chapter focuses on setting up the initial contexts for using JNDI and describing how to perform JNDI lookups.

This chapter covers the following topics:

- What You Need To Know About Oracle JNDI

- Configuring JNDI for Deployment

- Browsing the JNDI Context

- Looking Up Objects from J2EE Application Components

- Looking Up Objects from J2EE Application Clients

- JNDI State Replication

To use the information in this chapter, you should be familiar with the basics of JNDI and the JNDI API. For basic information about JNDI, including tutorials and the API documentation, visit the Sun Microsystems Web site at:

    http://java.sun.com/products/jndi/index.html

For more information about the other JNDI classes and methods, see the Javadoc at:

    http://java.sun.com/products/jndi/1.2/javadoc/index.html

JNDI Tasks

This chapter discusses the following common JNDI tasks:

- Configuring JNDI for Deployment

- Enabling JNDI State Replication

- Browsing the JNDI Context

- Constructing a JNDI Context

- Creating JNDI bindings and using JNDI to look up bindings, as described in the following sections:

  - Looking Up Objects from J2EE Application Components

  - Looking Up Objects from J2EE Application Clients

What's New for 10.1.3

The following OC4J JNDI features and behaviors are new for this release:

- JNDI Tree Browser - The Application Server Control Console provides a JNDI tree browser as described in Browsing the JNDI Context.

- Global JNDI Lookup - In the default OC4J configuration, lookups within an application are bound to be available within the current application's namespace. It is now possible to configure JNDI to perform inter-application lookups. Note that for global lookup to work properly, the target application's classes must be in the classpath of the application attempting the lookup. The simplest way to achieve this is to copy the target EJB jar into the `J2EE_HOME/applib` directory. This will cause OC4J to load this jar as a system library that is imported by all deployed applications. If finer-grained control of system libraries is desired, it is also possible to deploy the target classes as a named system library, and then explicitly import these into each application.

  Please consult the OC4J documentation on configuring a system library for the steps required to accomplish this. For configuration instructions, see "Configuring JNDI for Deployment".

- Relative Java Context Lookups - Relative lookups are now attempted when all other lookup attempts fail. For example, if a client looks up its resource using `context.lookup("ejb/EJBName")`, rather than ("`java:comp/env/ejb/EJBName`"), this lookup will now succeed. This lookup attempt is always relative to the "`java:comp/env`" namespace, and has the same effect as calling `context.lookup()` with the "`java:comp/env`" prefix attached to the binding name. There is no configuration required for this feature, since this feature is enabled by default in OC4J.

- Associating a Principal with a Thread

  For work that requires authentication or access control, you can now associate a principal, or user, with the thread that performs the work. This is described in "JNDI Contexts and Threads".

- MBean Support for JNDI - The following JNDI-related MBeans are now registered with OC4J and are available for use within the Oracle Enterprise Manager 10g Application Server Control Console:

  - `JNDIResource` - This JSR-77 MBean allows for queries on the JNDI bindings of a given application. A JNDIResource MBean is registered for each deployed application in a given OC4J instance. When an application is undeployed, the associated JNDIResource MBean is deregistered. This MBean offers two ways to access the JNDI bindings for a given application:

    - `getBindingsAsXMLString()` - returns the bindings tree as an XML document.

    - `getBindingsAsString()` - used mainly for debugging.

  - `JNDINamespace` - This MBean allows a client to iterate over all of the JNDIResource MBeans registered on a given OC4J instance. This means that this namespace bean can be used to view all of the JNDI bindings for a given application server instance, separated by application name. The method `getAllBindingsAsXMLString()` returns an XML document that represents the entire bindings tree.

  Both MBeans return XML documents that can be parsed to determine the current bindings of the applications deployed to an OC4J instance. This XML document uses the `oc4j-jndi-bindings-10_0.xsd` schema for validation.

  Path to JNDI-Related MBeans from the Application Server Control Page

  OC4J:Home > Administration tab > Task Name.System MBean Browser. Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone > JNDI Namespace and JNDI Resource

- Deprecated

  The following item is deprecated in this release:

  - The previous package structure for context factories provided by OC4J is deprecated, and is replaced by a more consistent naming structure. See the note below Table 2-1, "InitialContext Properties".

- No Longer Supported

  The following items are no longer supported in this release:

  - The `dedicated.connection` environment property is no longer supported as of release 10.1.3.

  - The `dedicated.rmicontext` environment property is no longer supported as of release 10.1.3. See Table 2-2, "JNDI-Related Environment Properties".

Additional Documentation

The How-To documents at the following site provide information about OC4J 10g Release 3 (10.1.3) features, including feature overviews and code excerpts relevant to the feature.

`http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

## 2.1 What You Need To Know About Oracle JNDI

The Java Naming and Directory Interface (JNDI) is a core part of the J2EE specification. JNDI provides naming and directory functionality for J2EE applications and components. JNDI is defined independently of any specific naming or directory service implementation. This enables J2EE applications and components to access different naming and directory services using a single API. Different naming and directory service provider interfaces (SPIs) can be plugged in behind this common API to handle different naming services.

A J2EE-compatible application uses JNDI to obtain naming contexts. A naming context enables the application to retrieve J2EE resources including data sources, local and remote Enterprise Java Beans (EJBs), and JMS-administered objects such as topics and queues.

Note: For information about controlling access to JNDI namespaces, see the Oracle Application Server Security Guide.

### 2.1.1 Configuring JNDI for Deployment

The only configuration necessary for JNDI is to enable global JNDI lookup.

To enable global lookups, make the following configuration changes: Set the `global-jndi-lookup-enabled` attribute to `true` in `server.xml`. This causes a lookup to be attempted across all known applications in the OC4J instance. If the lookup fails within the current application, the lookup is attempted on each deployed application's context. The first successful lookup of the given name is returned. This feature is disabled by default. When this feature is enabled, each resource binding name must be unique across all applications deployed in an OC4J instance. When a lookup across all applications is performed, the order of applications is not guaranteed. If two applications in the same instance have a binding of the same name pointing to different objects, then a lookup might return an unexpected object when using this new feature.

For reference documentation of `server.xml`, see Oracle Containers for J2EE Configuration and Administration Guide Appendix B - Configuration Files Used in OC4J, Section - "Overview of the OC4J Server Configuration File (server.xml)".

## 2.2 Initial Context

The concept of the initial context is central to JNDI. This section discusses the following topics:

### 2.2.1 Creating and Using the Initial Context

The two most frequently used JNDI operations in J2EE applications are:

- Creating a new `javax.naming.InitialContext` instance

- Using the `InitialContext` to look up a resource

When OC4J starts up, it constructs a JNDI initial context for each application by reading the resource references in each application's deployment descriptor.

- For lookups from within EJBs, the resource references are specified in `ejb-jar.xml`. Resource references specified in `ejb-jar.xml` are then mapped to actual JNDI locations in `orion-ejb-jar.xml`.

- When a servlet creates an initial context, the JNDI implementation maps bindings to the resource references specified in `web.xml` to the actual JNDI locations specified in `orion-web.xml`.

- An application client's `application-client.xml` descriptor's references are bound when the context is created from a remote application client. These references are bound to the actual JNDI locations specified in `orion-application-client.xml`.

Persistence

After the initial configuration, the JNDI namespace for each application is purely memory-based. Additions made to the context at run time are not persisted.

When OC4J is shut down, any bindings made programmatically (by making a call to `Context.bind`, for example) are no longer available.

Bindings that are specified declaratively through J2EE deployment descriptors are persisted beyond a shutdown of the application server.

### 2.2.2 Constructing a JNDI Context

Upon initialization, OC4J constructs a JNDI context for each application that is deployed in the server. There is always at least one application for an OC4J server, the global application, which is the default parent for each application in a server instance. User applications inherit properties and bindings from the global application and can override property values defined in the global application, specify new values for properties, and define new properties as required. Lookups in a user application's context are made in the following order:

- First, look in the local application's namespace.

- If the binding is not found locally, then look for the binding in the parent application.

- If the binding is not found locally or in the parent application, then one of the following occurs:

  - If global lookup is enabled, then OC4J will attempt to resolve the lookup over all known application contexts currently deployed in the OC4J instance.

  - If global lookup is not enabled (which is the default behavior), then a `NameNotFoundException` is thrown.

For more information about configuring the OC4J server and its contained applications, see the Oracle Containers for J2EE Configuration and Administration Guide.

Environment and Constructors

The environment that OC4J uses to construct a JNDI initial context can be found in three places:

- An environment specified explicitly in a `java.util.Hashtable` instance passed to the JNDI initial context constructor. ("Example: Application Client Looking Up an EJB" includes an example of this constructor.)

- System property values, as set either by the OC4J server or by the application container.

- A `jndi.properties` file contained in the application EAR file (as part of `application-client.jar`).

The JNDI `InitialContext` has two constructors. You can use either of the following constructors to create the initial context:

    InitialContext()
    InitialContext(Hashtable env)

InitialContext()

The `InitialContext()` constructor creates a `Context` object using the default context environment. If you use this constructor in an OC4J server-side application, then the application context built by OC4J upon startup is returned. This constructor is typically used in code that runs on the server side, such as JSPs, EJBs, and servlets.

InitialContext(Hashtable env)

The `InitialContext(Hashtable env)` constructor takes an environment parameter. You normally use this form of the `InitialContext` constructor in remote client applications, where it is necessary to specify the JNDI environment. The `env` parameter in this constructor is a `java.util.Hashtable` that contains properties required by JNDI. Table 2-1 lists these properties, which are defined in the `javax.naming.Context` interface.

Table 2-1 InitialContext Properties

Property | Value | Meaning
--- | --- | ---
`java.naming.factory.initial` | `INITIAL_CONTEXT_FACTORY` | This property specifies which initial context factory to use when creating a new initial context object. The eligible settings are: `oracle.j2ee.rmi.RMIInitialContextFactory` `oracle.j2ee.naming.ApplicationClientInitialContextFactory` `oracle.j2ee.iiop.IIOPInitialContextFactory` See the Note following this table for information about deprecated context factories.
`java.naming.provider.url` | `PROVIDER_URL` | This property specifies the URL that the client-side JNDI code uses to look up objects on the server. See Table 2-2, "JNDI-Related Environment Properties" for details.
`java.naming.security.principal` | `SECURITY_PRINCIPAL` | This property specifies the user name for the current security credentials. Required in application client code to authenticate the client. Not required for server-side code, because the authentication has already been performed.
`java.naming.security.credential` | `SECURITY_CREDENTIALS` | This property specifies the password for the current security principal. Required in application client code to authenticate the client. Not required for server-side code, because the authentication has already been performed.

See "Example: Application Client Looking Up an EJB" for a code example that sets these properties and gets a new JNDI initial context.

Note: The use of the 10g package names for OC4J initial context factories is deprecated as of 10.1.3. The following context factories are deprecated: `com.evermind.server.rmi.RMIInitialContextFactory` `com.evermind.server.ApplicationClientInitialContextFactory` `com.oracle.iiop.server.IIOPInitialContextFactory` For the new context factory names that replace the deprecated ones, see the `java.naming.factory.initial` item in Table 2-1, "InitialContext Properties".

#### 2.2.2.1 Example: Looking Up An EJB

This example shows code to use on the server side in a typical Web or EJB application:

    Context ctx = new InitialContext();
    HelloHome myhome = (HelloHome) ctx.lookup("java:comp/env/ejb/myEJB");

The first statement creates a new initial context object, using the default environment. The second statement looks up an EJB home interface reference in the application's JNDI tree.

In this case, `myEJB` is the name of a reference to a session bean that is declared in `web.xml` (if this code executes in a servlet), or in `ejb-jar.xml` (if this code executes in an EJB business method). This reference is defined in an `<ejb-ref>` tag. The EJB reference would then be mapped to an actual JNDI location in either `orion-web.xml` or `orion-ejb-jar.xml`, depending on the caller that is executing this code.

For example:

    <ejb-ref>
      <ejb-ref-name>ejb/myEJB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <home>myEjb.HelloHome</home>
      <remote>myEjb.HelloRemote</remote>
    </ejb-ref>

### 2.2.3 JNDI Contexts and Threads

By default, when you create a JNDI Context with a username and password, a principal or user is bound to a context instance when establishing an initial context with OC4J. Thus, the specified principal or user is used during authentication and access control when looking up a named object in the OC4J namespace, obtaining a reference to a remote object, and invoking operations on the remote object. In this scenario, multiple threads within an application client may share the context.

You can also associate a principal or user with the thread that will perform the work. To do so, create a context with the appropriate principal and credential property values as described below. To disassociate a principal from the thread, close the context.

When a thread is associated with a principal, that principal becomes the default for the thread. If any contexts are subsequently created without principal or credential properties, the principal associated with the thread will remain unchanged.

While it is technically possible to share a single context among multiple threads, passing a context to another thread does not associate the principal used in creating the context with the new thread. The only way to associate a principal with a new thread is to create a new context within that thread. In addition, a context can only be closed within the thread with which it was created. For these reasons, Oracle recommends that all work performed with a given context be handled in the same thread.

A thread may be associated with only one principal at any given time. If multiple contexts are created within a single thread without closing any contexts, the thread will be associated with the principal used in the last context created. Principal information is stored with the thread in a stack. If the last context is closed, the thread becomes associated with the principal used in creating the previous context, and so on.

To enable this feature in 10.1.3, set the system property `-DAssociateUserToThread=true` on the command line. By default, this feature is not enabled (set to `false`).

## 2.3 Browsing the JNDI Context

Using the JNDI Browser, you can view the entire JNDI namespace to verify that a given set of objects is actually bound in an application.

The JNDI Browser is available within the Oracle Enterprise Manager 10g Application Server Control Console as follows:

Path to JNDI Browser

OC4J: Home > Administration tab > Task Name: Services > JNDI Browser > Click Go To Task icon > Expand All

To Get JNDI Bindings as a String

You can also get a string representation of the bindings in a JNDI context. This can be useful in debugging.

OC4J: Home > Administration tab > Task Name: System MBean Browser. Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JNDIResource > Select application > Operations tab > `getBindingsAsString` or `getBindingsAsXMLString` > Invoke

## 2.4 Looking Up Objects from J2EE Application Components

This section describes how to use the JNDI to look up bound objects from J2EE application components, such as servlets, JSP pages, and EJBs.

You can use initial context factories in OC4J to access objects from J2EE application components:

- Looking Up Objects In the Same Application

- Looking Up Objects in Another Application

### 2.4.1 Looking Up Objects In the Same Application

When code is running in a server, it is by definition part of an application. Because the code is part of an application, OC4J establishes defaults for properties that JNDI uses. Application code, such as a servlet or an EJB business method, does not need to provide any property values when constructing a JNDI `InitialContext` object.

Note: If your application must look up a remote reference, such as a resource in another J2EE application in the same JVM or a resource external to any J2EE application, then you must use `RMIInitialContextFactory` or `IIOPInitialContextFactory`. See "Looking Up Objects in Another Application".

#### 2.4.1.1 Example: Servlet Looking Up a Data Source

In this example, a servlet retrieves a data source to perform a JDBC operation on a database.

Use the Application Server Control Console to specify data source location. Specify the location in the JNDI Location field of the Create Data Source page. See Chapter 4, "Data Sources".

The servlet's `web.xml` file defines the following resource:

    <resource-ref>
       <description>
          A data source for the database in which
          the EmployeeService enterprise bean will
          record a log of all transactions.
       </description>
       <res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
       <res-type>javax.sql.DataSource</res-type>
       <res-auth>Container</res-auth>
       <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

The corresponding `orion-web.xml` mapping is:

    <resource-ref-mapping name="jdbc/EmployeeAppDB" location="jdbc/pool/OracleCache" />

The `name` value is the same as that specified in the `<res-ref-name>` element in `web.xml`.

The `location` value corresponds to the `"jndi-name"` attribute in the `<data-source>` element of `data-sources.xml`.

In this case, the following code in the servlet returns the correct reference to the data source object:

    ...
    try {
      InitialContext ic = new InitialContext();
      ds = (DataSource) ic.lookup("java:comp/env/jdbc/EmployeeAppDB");
      ...
    }
    catch (NamingException ne) {
      throw new ServletException(ne);
    }
    ...

When looking up objects within the same application, no initial context factory specification is necessary, because OC4J sets appropriate defaults when the application starts. For most lookups within the same application, only the `no-args` constructor for `javax.naming.InitialContext` to create an InitialContext is required.

Also, it is not necessary to supply a provider URL in this case, because no URL is required to look up an object contained within the same application or under `java:comp/`.

Note: Some versions of the JDK on some platforms automatically set the system property `java.naming.factory.url.pkgs` to include `com.sun.java.*`. Check this property and remove `com.sun.java.*` if it is present.

### 2.4.2 Looking Up Objects in Another Application

Use one of the following context factories to access objects in another application, or to access J2EE resources from a standalone java client:

- `oracle.j2ee.rmi.RMIInitialContextFactory`

- `oracle.j2ee.iiop.IIOPInitialContextFactory`

- `oracle.j2ee.naming.ApplicationClientInitialContextFactory`

#### 2.4.2.1 RMIInitialContextFactory

The RMIInitialContexFactory provides a JNDI context implementation that uses the Oracle Remote Method Invocation (RMI) protocol for distributed lookups. This context factory is used by remote clients, as well as applications that attempt lookups for bindings deployed in other OC4J instances. The JNDI environment properties used by the `RMIInitialContextFactory` are described in Table 2-2, "JNDI-Related Environment Properties". For information on RMI, see the "Using Remote Method Invocation in OC4J" chapter.

##### 2.4.2.1.1 Example: Servlet Looking Up an EJB Remotely Using RMI

In this example, a servlet accesses an EJB running on another OC4J instance on a different machine. The EJB in this example is the `EmployeeBean` that is used in the "Example: Application Client Looking Up an EJB".

Here is an excerpt of the servlet code:

    Hashtable env = new Hashtable();
    env.put("java.naming.factory.initial",
    "oracle.j2ee.rmi.RMIInitialContextFactory");
    env.put("java.naming.provider.url","ormi://remotehost/bmpapp");
    env.put("java.naming.security.principal","SCOTT");
    env.put("java.naming.security.credentials","TIGER");
    Context context = new InitialContext(env);
    Object homeObject =
    context.lookup("EmployeeBean");

##### 2.4.2.1.2 Example: Servlet Looking Up an EJB Remotely in a Multiple Instance Environment

When running OC4J within IAS, a remote JNDI service can specify that the request should use the `"opmn:ormi"` protocol, which allows a client to attempt a lookup without hard-coding the ORMI port information. The OC4J JNDI code contacts the opmn process to determine the proper ORMI port for this IAS install. The lookup is similar to the above ORMI example, except that the `"java.naming.provider.url"` property is set to a URL that begins with `"opmn:ormi"`. Here is an excerpt of the same lookup code, using `"opmn:ormi"`:

Here is an excerpt of the servlet code:

    Hashtable env = new Hashtable();
    env.put("java.naming.factory.initial",
    "oracle.j2ee.rmi.RMIInitialContextFactory");
    env.put("java.naming.provider.url","opmn:ormi://remotehost/bmpapp");
    env.put("java.naming.security.principal","SCOTT");
    env.put("java.naming.security.credentials","TIGER");
    Context context = new InitialContext(env);
    Object homeObject =
    context.lookup("EmployeeBean");

There are also ways to specify which home instance the "opmn" URL should refer to. For more information on using "opmn", see Using Remote Method Invocation in OC4J.

#### 2.4.2.2 IIOPInitial ContextFactory

The `IIOPInitialContexFactory` provides a JNDI Context implementation that uses the Internet Inter-ORB Protocol (IIOP) for distributed lookups. For information on RMI, see the "Using Remote Method Invocation in OC4J" chapter.

The conditions under which to use `IIOPInitialContextFactory` are the same as those for `RMIInitialContextFactory` except that the remote protocol is IIOP instead of ORMI.

Note: You can use `IIOPInitialContextFactory` only for looking up EJBs. The same holds true for using a `"corbaname"` URL with the `ApplicationClientInitialContextFactory`.

##### 2.4.2.2.1 Example: Servlet Looking Up an EJB Remotely Using IIOP

Here is an example.

    Hashtable env = new Hashtable();
    env.put("java.naming.factory.initial",
    "oracle.j2ee.iiop.IIOPInitialContextFactory");
    env.put("java.naming.provider.url","corbaname::remotehost:PORT_NUMBER#APPLICATION_NAME");
    env.put("java.naming.security.principal","SCOTT");
    env.put("java.naming.security.credentials","TIGER");
    Context context = new InitialContext(env);
    Object homeObject =
    context.lookup("EmployeeBean");

In this example, a `corbaname` URL is used to specify the location of the EJB. In the `corbaname` string provided in the above example, `PORT_NUMBER` is the IIOP port number that OC4J is configured to use, `remotehost` is the name of the server that OC4J is running on, and `APPLICATION_NAME` is the name of the application that contains the EJB.

The application used in this example must be deployed with IIOP enabled for this lookup to succeed. The remote client must also include the IIOP client jar generated by OC4J. For more information on this, see the OC4J IIOP documentation at "Switching from ORMI to IIOP Transport".

## 2.5 Looking Up Objects from J2EE Application Clients

This section discusses how to configure an application client to access objects running inside an OC4J instance.

Section 9.1 of the J2EE 1.3 specification defines application clients as follows:

"... first tier client programs that execute in their own Java virtual machines. Application clients follow the model for Java technology-based applications: they are invoked at their main method and run until the virtual machine is terminated. However, like other J2EE application components, application clients depend on a container to provide system services. The application client container may be very light-weight compared to other J2EE containers, providing only the security and deployment services described [in this specification]."

When an application client must look up a resource that is available in a J2EE server application, the client uses the `ApplicationClientInitialContextFactory` in the `oracle.j2ee.naming` package to construct the initial context.

Note: If your application is a J2EE application client (that is, it has an `application-client.xml` file), then you must always use `ApplicationClientInitialContextFactory` regardless of the protocol (ORMI or IIOP) that the client application is using. The protocol itself is specified by the JNDI property `java.naming.provider.url`. See Table 2-2, "JNDI-Related Environment Properties" for details.

Remote and local access of components is essentially the same from the point of view of the remote client. Clients can use ORMI or IIOP, depending on the provider URL.

Consider an application client that consists of Java code that connects to an OC4J server. For example, the client code is running on a workstation and might connect to a server object, such as an EJB, to perform some application task. In this case, the remote client must specify the value of the property `java.naming.factory.initial` as `"oracle.j2ee.naming.ApplicationClientInitialContextFactory"`. This can be specified in client code, or it can be specified in the `jndi.properties` file that is part of the application's `application-client.jar` file included in the EAR file.

To have access to remote objects that are part of the application, `ApplicationClientInitialContextFactory` reads the `META-INF/application-client.xml` file and the `META-INF/orion-application-client.xml` file in the `application-client.jar` file.

### 2.5.1 Environment Properties

If the ORMI protocol is being used, then `ApplicationClientInitialContextFactory` reads the properties listed in Table 2-2 from the environment.

Table 2-2 J NDI-Related Environment Properties

Property | Meaning
--- | ---
`dedicated.rmicontext` | This property is no longer used by OC4J. This property previously was used for two reasons: To enable load balancing. As a workaround for known ORMI/JNDI bugs. In Version 10.1.3, the known ORMI /JNDI bugs that required this flag have been resolved. To enable client-side ORMI load-balancing in 10.1.3, please use the properties described in the "Load Balancing" section. The properties described in the "Load Balancing" section can be used in the few cases that would still require this flag.
`java.naming.provider.url` | This property specifies the URL to use when looking for local or remote objects. The format is either
    [opmn:|http:|https:]ormi://hostname/appname
or
     corbaname:hostname:port
For details on the `corbaname` URL, see "Specifying the corbaname URL" . You can supply multiple hosts (for failover) in a comma-separated list when using the ORMI protocol.
`java.naming.factory.url.pkgs` | Some versions of the JDK on some platforms automatically set the system property `java.naming.factory.url.pkgs` to include `com.sun.java.*`. Check this property and remove `com.sun.java.*` if it is present.
`Context.SECURITY_PRINCIPAL` | This property specifies the user name and is required in client-side code to authenticate the client. It is not required for server-side code because authentication has already been performed. This property name is also defined as `java.naming.security.principal`.
`Context.SECURITY_CREDENTIAL` | This property specifies the password and is required in client-side code to authenticate the client. It is not required for server-side code because authentication has already been performed. This property name is also defined as `java.naming.security.credentials`.

### 2.5.2 Load Balancing

In situations where heavy request volume is expected, load balancing of requests across OC4J instances may be desired. Load balancing is configurable using the `oracle.j2ee.rmi.loadBalance` property, which can be set in the client's `jndi.properties` file or in a Hashtable in the client code. The values for this the `oracle.j2ee.rmi.loadBalance` property are outlined in the following table.

Table 2-3 oracle.j2ee.rmi.loadBalance Property Values

Value | Description
--- | ---
`client` | If specified, the client interacts with the OC4J process that was initially chosen at the first lookup for the entire conversation.
`context` | Used for a Web client (servlet or JSP) that will access EJBs in a clustered OC4J environment. If specified, a new `Context` object for a randomly-selected OC4J instance will be returned each time `InitialContext()` is invoked.
`lookup` | Used for a standalone client that will access EJBs in a clustered OC4J environment. If specified, a new `Context` object for a randomly-selected OC4J instance will be created each time the client calls `Context.lookup()`.

For more information on load balancing see "Configuring ORMI Request Load Balancing".

### 2.5.3 Example: Application Client Looking Up an EJB

This section shows how to configure an application client to access an EJB running inside an OC4J instance.

First, the EJB is deployed into OC4J. with the name `EmployeeBean`. The name is defined as follows in `ejb-jar.xml`:

    <ejb-jar>
      <display-name>bmpapp</display-name>
      <description>
         An EJB app containing only one Bean Managed Persistence Entity Bean
      </description>
      <enterprise-beans>
         <entity>
            <description>no description</description>
            <display-name>EmployeeBean</display-name>
            <ejb-name>EmployeeBean</ejb-name>
            <home>bmpapp.EmployeeHome</home>
            <remote>bmpapp.Employee</remote>
            <ejb-class>bmpapp.EmployeeBean</ejb-class>
            <persistence-type>Bean</persistence-type>
            ...
         </entity>
      </enterprise-beans>
    ..
    </ejb-jar>

The EJB `EmployeeBean` is bound to the JNDI location `bmpapp/EmployeeBean` in `orion-ejb-jar.xml` as follows:

    <orion-ejb-jar>
       <enterprise-beans>
           <entity-deployment name="EmployeeBean"
               location="bmpapp/EmployeeBean" table="EMP">
                            ...
           </entity-deployment>
                            ...
       </enterprise-beans>
               ...
    </orion-ejb-jar>

The application client program uses the `EmployeeBean` EJB, and refers to it as `EmployeeBean`.

An excerpt from the application client program follows:

    public static void main (String args[])
    {
     ...
     Context context = new InitialContext();
     /**
      * Look up the EmployeeHome object. The reference is retrieved from the
      * application environment naming context (java:comp/env). The ejb reference is
      * specified in the assembly descriptor (META-INF/application-client.xml).
      */
     Object homeObject =
         context.lookup("java:comp/env/EmployeeBean");
     // Narrow the reference to an EmployeeHome.
     EmployeeHome home =
         (EmployeeHome) PortableRemoteObject.narrow(homeObject,
                                                    EmployeeHome.class);
     // Create a new record.
     Employee rec = home.create(empNo, empName, salary);
     // call method on the EJB
     rec.doSomething();
     ...
    }

Note that we are not passing a hash table when creating a context in the line:

    Context context = new InitialContext();

This is because the context is created with values read from the `jndi.properties` file, which in this example contains:

    java.naming.factory.initial=oracle.j2ee.naming.ApplicationClientInitialContextFactory
    java.naming.provider.url=ormi://localhost/bmpapp
    java.naming.security.principal=SCOTT
    java.naming.security.credentials=TIGER

Alternatively, you can pass a hash table to the constructor of `InitialContext` instead of supplying a `jndi.properties` file. The code looks like this:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.naming.ApplicationClientInitialContextFactory");
    env.put("java.naming.provider.url","ormi://localhost/bmpapp");
    env.put("java.naming.security.principal","SCOTT");
    env.put("java.naming.security.credentials","TIGER");
    Context initial = new InitialContext(env);

Because the application client code refers to the `EmployeeBean` EJB, you must declare this in the `<ejb-ref>` element in the `application-client.xml` file:

    <application-client>
       <display-name>EmployeeBean</display-name>
       <ejb-ref>
           <ejb-ref-name>EmployeeBean</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>bmpapp.EmployeeHome</home>
           <remote>bmpapp.Employee</remote>
       </ejb-ref>
    </application-client>

Recall that the `EmployeeBean` EJB is bound to the JNDI location `bmpapp/EmployeeBean` as configured in the `orion-ejb-jar.xml` file. You must map the EJB reference name used in the application client program to the JNDI location where the EJB is actually bound to in `orion-ejb-jar.xml`. Do this in the `orion-application-client.xml` file:

    orion-application-client.xml file:
    <orion-application-client>
       <ejb-ref-mapping name="EmployeeBean" location="bmpapp/EmployeeBean" />
    </orion-application-client>

For details on the `application-client.xml` file and the `orion-application-client.xml` file, see Oracle Containers for J2EE Developer's Guide, Appendix A, OC4J-Specific Deployment Descriptors.

### 2.5.4 Example: Application Client Looking Up an EJB Using IIOP

In the previous example, the application client used ORMI as the underlying protocol for remote lookups of resources. Alternatively, you can configure the application client to use IIOP as the remote protocol. The code for looking up the `EmployeeBean` is the same as the previous example, with the following differences:

The `jndi.properties` file must be changed to reflect the fact that IIOP is being used as the remote protocol. This is configured in the `java.naming.provider.url` system property in `jndi.properties`. The following is the `jndi.properties` file for the same example, configured to use IIOP:

    java.naming.factory.initial=oracle.j2ee.naming.ApplicationClientInitialContextFactory
    java.naming.provider.url=corbaname::REMOTE_HOST:IIOP_PORT#bmpapp
    java.naming.security.principal=SCOTT
    java.naming.security.credentials=TIGER

Alternatively, you can pass a hash table to the constructor of `InitialContext` instead of supplying a `jndi.properties` file to use IIOP as the underlying protocol. The code looks like this:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.naming.ApplicationClientInitialContextFactory");
    env.put("java.naming.provider.url","corbaname::REMOTE_HOST:IIOP_PORT#bmpapp");
    env.put("java.naming.security.principal","SCOTT");
    env.put("java.naming.security.credentials","TIGER");
    Context initial = new InitialContext(env);

If an application client sets the JNDI properties through a hash table, as shown in this example, the security credentials must be set as system properties. The IIOP interceptors require access to the client's credentials through system properties. This is achieved automatically when using the `jndi.properties` file, since the JNDI framework automatically sets these properties as system properties.

If the properties are set in the code itself, the following lines must be added to the client code:

    System.setProperty("java.naming.security.principal","SCOTT");
    System.setProperty("java.naming.security.credentials ","TIGER");

In both the `jndi.properties` file and the programmatic example,

- `REMOTE_HOST` must be set to the name of the server running the OC4J server.

- `IIOP_PORT` must be set to the port number used by OC4Jfor serving IIOP requests.

When using IIOP with the application client, no changes need to be made to the application client code or the deployment descriptors. The client must be configured to use IIOP properly, including the use of the `jndi.properties` file.

The remote application client must also include the deployed application's IIOP client jar in its classpath, in order to have access to the IIOP stubs for each EJB deployed.

See "Switching from ORMI to IIOP Transport" for more information on this.

## 2.6 JNDI State Replication

This section discusses JNDI state replication.

Note: JNDI State Replication supports clustering in a multiple-OC4J environment. If you are using Oracle Application Server in standalone mode as an environment for developing applications to be used in a multiple-OC4j environment, the information in this section is provided to support your planning and coding process.

The section covers the following topics:

- What Is JNDI State Replication

- Enabling JNDI State Replication

- Limitations of JNDI State Replication

### 2.6.1 What Is JNDI State Replication

JNDI state replication causes changes made to the context on one OC4J instance of an OC4J cluster to be replicated to the name space of every other OC4J instance in the cluster.

When JNDI state replication is enabled, you can bind a serializable value into an application context (using a remote client, EJB, or servlet) on one server and read it on another server.

### 2.6.2 Enabling JNDI State Replication

JNDI state replication is enabled on a per-application basis. When an application is deployed, a `<cluster>` tag can be added to `orion-application.xml`, which is found in the application's `META-INF` directory. This type of configuration allows for control over the clustering status of each application. Adding this `<cluster>` tag enables HTTP/EJB session replication as well as JNDI State replication.

The `<cluster>` element serves as the single mechanism for clustering configuration. You can add the `<cluster>` element to either of the following files:

- The `ORACLE_HOME/j2ee/home/config/application.xml` file to configure clustering at the global level.

- An application-specific `orion-application.xml` file for per-application clustering configuration.

Configuring the `<cluster>` element mainly involves specifying the following subelements:

- The `<replication-policy>` subelement controls when replication occurs and what data is replicated.

- The `<protocol>` subelement defines what mechanism to use for replication - `multicast` (default), `peer-to-peer`, or `database`.

Here are two example OC4J clustering and JNDI state replication configuration.

Example 1:

This example configures an application to communicate over a multicast network. It is important to make sure that all nodes in this cluster use the same multicast port.

    <cluster>
        <protocol>
            <multicast ip="230.230.0.30" port="45678" />
        </protocol>
    </cluster>

Example 2:

This example uses a peer-to-peer protocol for JNDI state replication. This example requires that all nodes running in the cluster be part of a managed IAS instance. This Oracle Application Server instance is controlled by OPMN.

    <cluster>
        <replication-policy trigger="onRequestEnd" scope="modifiedAttributes" />
        <protocol>
            <peer>
                <opmn-discovery/>
            </peer>
        </protocol>
    </cluster>

For detailed information on OC4J clustering, see the Oracle Containers for J2EE Configuration and Administration Guide.

### 2.6.3 Limitations of JNDI State Replication

Consider the following limitations when relying on JNDI state replication:

- Propagating Changes Across the Cluster

- Binding a Remote Object

#### 2.6.3.1 Propagating Changes Across the Cluster

Bindings to values that are not serializable are not propagated across the cluster.

#### 2.6.3.2 Binding a Remote Object

If you bind a remote object (typically a `home` or `EJB` object) in an application context, then that JNDI object is shared across the cluster but there is a single point of failure in the first server to which it is bound.