Skip Headers
Oracle® Containers for J2EE Services Guide
10g Release 3 (10.1.3)
B14427-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
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:

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:

What's New for 10.1.3

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

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:

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 JNDI-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:

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:

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.