Skip Headers

Oracle9iAS Containers for J2EE Services Guide
Release 2 (9.0.2)

Part Number A95879-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

2
Java Naming and Directory Interface

This chapter describes the Java Naming and Directory Interface (JNDI) service implemented by Oracle9iAS Containers for J2EE (OC4J) applications. The JNDI chapter covers the following topics:

Introduction

JNDI is specified as part of J2EE, and provides naming and directory functionality for Java applications. JNDI is defined independently of any specific naming or directory service implementation, so it enables Java applications to access different, possibly multiple, 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.

Before reading 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

JNDI, in the form of jndi.jar, is available with OC4J. Your application can take advantage of the JNDI API without having to provide any other libraries or JAR files. J2EE-compatible applications use JNDI to obtain naming contexts that enable the application to locate and retrieve objects such as data sources, local and remote EJBs, JMS services, and many other J2EE objects and services.

Initial Context

Central to JNDI is the concept of the initial context. The two most often-used JNDI operations in J2EE applications are:

  1. Creating a new InitialContext object.

  2. Using the InitialContext, looking up a J2EE or other resource.

When OC4J starts up, it constructs a JNDI initial context for each application by reading each of the application's configuration XML files that can contain resource references. Applications are defined in the server.xml configuration file.


Note:

After the initial configuration, the JNDI tree for each application is purely memory-based. Additions that are made to the context are not persisted. When OC4J is restarted, any new bindings that were made in application code are no longer available.


The following example shows two lines of Java code that would be used on the server side in a typical Web or EJB application:

Context ctx = new InitialContext();
myEJBHome 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 might be the name of a session bean that is declared in the orion-web.xml (or web.xml) configuration file, in an <ejb-ref> tag. 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>

This chapter focuses on setting up the JNDI initial contexts for using JNDI, and on describing how OC4J performs JNDI look ups. 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

Constructing a JNDI Context

When OC4J starts up, it constructs a JNDI context for each application that is deployed in the server (in server.xml). 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-written applications inherit properties from the global application. User-written applications can override property values defined in the global application, can define new values for properties, and can define new properties as required.

In the default OC4J server, as shipped, the global application is the default application, as defined in server.xml. For more information about configuring the OC4J server and its contained applications, see the Oracle9iAS Containers for J2EE User's Guide, in particular the "Advanced Information" chapter.

The environment that OC4J uses to construct a JNDI initial context can be found in several places. These include:

The JNDI Environment

The JNDI InitialContext has two constructors:

InitialContext()
InitialContext(Hashtable env)

The first constructor creates a Context object using the default context environment. If this constructor is used in an OC4J server-side application, the initial context is created using the default environment for that application, created by OC4J when the server is started. This constructor is the one typically used in code that runs on the server side, such as in a JSP, servlet, or EJB.

The second constructor takes an environment parameter. The second form of the InitialContext constructor is normally used in client applications, where it is necessary to specify the JNDI environment. The env parameter in this constructor is a Hashtable that contains properties required by JNDI. These properties are:

INITIAL_CONTEXT_FACTORY

A value for the java.naming.factory.initial property that specifies which initial context factory to use when creating a new initial context object.

PROVIDER_URL

The URL that application client code uses to look up objects on the server. Also used by the RMIInitialContextFactory to search for objects in different applications.

SECURITY_PRINCIPAL

The user name. Required in application client code to authenticate the client. Not required for server-side code, since the authentication has already been done.

SECURITY_CREDENTIAL

The password. Required in application client code to authenticate the client. Not required for server-side code, since the authentication has already been done.

See "Remote Client Example" for a code example that sets these properties and gets a new JNDI initial context.

Initial Context Factories

There are three JNDI initial context factories that are available for use by application code. They are

The following sections describe each of these factories and their uses in OC4J applications.

ApplicationClientInitialContextFactory

When an application client needs to look up a resource that is available in a J2EE server application, the client uses ApplicationClientInitialContextFactory as to construct the initial context.

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

In order to have access to remote objects that are part of the application, ApplicationClientInitialContextFactory reads the META-INF/application-client.xml and META-INF/orion-application-client.xml files in the <application_name>-client.jar file.

Using the ApplicationClientInitialContextFactory to construct JNDI initial contexts means that the client can look up local objects (objects contained in the immediate application, or in its parent application) using the java:comp/env mechanism, and can use ORMI to look up remote objects.

Environment Properties

ApplicationClientInitialContextFactory invokes RMIInitialContextFactory to read the following properties from the environment:

dedicated.connection

Each JNDI lookup retrieves a connection to the server. Each subsequent JNDI lookup for this same server uses the connection returned by the first JNDI lookup. That is, all requests are forwarded over and share the same connection.

The dedicated.connection JNDI property overrides this default behavior. If you set dedicated.connection to true before you retrieve an InitialContext, you will retrieve a separate physical connection for each lookup, each with its own designated username/password.

dedicated.connection defaults to false. Reset to true if:

  1. You want to connect using a different username/password each time. ORMI connections are associated with an authenticated ID; setting this property to true will open a new connection instead of reusing a cached connection. If this property is set to false, the first username/password is used for all subsequent connections, even when an alternate username/password is supplied.

  2. You want to make a remote connection, look up an object on the remote connection, then look up the same object locally.

java.naming.provider.url

The URL to use when looking for local or remote objects. The format is
[http: | https:]ormi://<hostname>/<app_name>
Multiple hosts can be supplied in a comma-separated list, for failover.

http.tunnel.path

Specifies an alternative RMIHttpTunnelServlet path. The default path is /servlet/rmi, as bound to the target site's web-app.

context.SECURITY_PRINCIPAL

The user name. Required in application client code to authenticate the client. Not required for server-side code, since the authentication has already been done.

context.SECURITY_CREDENTIAL

The password. Required in application client code to authenticate the client. Not required for server-side code, since the authentication has already been done.

Remote Client Example

The following example code shows how JNDI properties can be specified in a client application:

...
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.ApplicationClientInitialContextFactory"); env.put(Context.PROVIDER_URL, "ormi://<hostname>/employee"); env.put(Context.SECURITY_PRINCIPAL, "admin"); env.put(Context.SECURITY_CREDENTIALS, "welcome"); Context context = new InitialContext(env); //do the lookups... ...

Server-Side Clients

Server-side clients need not specify an InitialContextFactory in order to look up resources defined within the client application. By default, server-side clients have InitialContextFactory set to ApplicationInitialContextFactory. This allows clients to perform lookups using names in the style java:comp:/env.

To look up resources that are not defined within the client application, clients must set the InitialContextFactory to RMIInitialContextFactory and look up the resources or EJB using an explicit URL.

ApplicationInitialContextFactory

When code is running in a server, it is by definition part of an application. So as part of an application, OC4J can establish defaults for properties that JNDI uses. For the java.naming.factory.initial property, OC4J sets ApplicationInitialContextFactory as the default value for this system property.

When this context factory is being used, the ApplicationContext is specific to the current application, so all of the references specified in files such as web.xml, orion-web.xml, or ejb-jar.xml for that application are available. This means that a lookup using java:comp/env works for any resource that the application has specified. Lookups using this factory are done locally in the same virtual machine.

However, using the default ApplicationInitialContextFactory means that only application-local resources are available using the java:comp/env lookup mechanism. If your application needs to look up a remote reference, either a resource in another J2EE application or perhaps a resource external to any J2EE application, then you must use RMIInitialContextFactory.

Example

As a concrete example, consider a servlet that needs to get a data source to do a JDBC operation on a database. The data source reference is mapped in orion-web.xml as

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

The data source location is specified in data-sources.xml as:

<data-source
    class="oracle.jdbc.pool.OracleConnectionCacheImpl"
    location="jdbc/pool/OracleCache"
    username="hr"
    password="hr"
    url="jdbc:oracle:thin:@<hostname>:<TTC port>:<DB ID>"
/>

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/OracleDS1");
  ...
}
catch (NamingException ne) {
  throw new ServletException(ne);
}
...

No initial context factory specification is needed, as OC4J sets ApplicationInitialContextFactory as the default value of the system property java.naming.factory.initial when the application starts.

There is no need to supply a provider URL in this case, as 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.* . You should check this property and remove com.sun.java.* if present.


Note that an application can use the java:comp/env mechanism to look up resources that are specified not only in its own name space, but also in the name spaces of any declared parent applications, or in the global application (which is the default parent if no specific parent application was declared).

RMIInitialContextFactory

Using either the default server-side ApplicationInitialContextFactory, or specifying ApplicationClientInitialContextFactory, will work for most application purposes.

There are some cases, however, in which an additional context factory must be used:

  1. When looking up an object that is part of another J2EE application, and for which a resource reference either cannot be or is not specified in the current application's application-client.xml file.

  2. When doing a general lookup for external JNDI objects, that may or may not be part of a J2EE application. A generalized JNDI object browser would be an example of this usage.

  3. When accessing the entire remote JNDI namespace, as opposed to a specific application context. For further details, see:

    http://www.orionserver.com/docs/remote-access/remote-access.xml
    

The RMIInitialContextFactory uses the same environment properties that are used by ApplicationClientInitialContextFactory, namely:

Remote Client Example

The following code could be used to look up a remote object using RMIInitialContextFactory:

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.evermind.server.rmi.RMIInitialContextFactory"); env.put("java.naming.provider.url","ormi://localhost/ejbsamples"); env.put("java.naming.security.principal","admin"); env.put("java.naming.security.credentials","welcome"); Context context = new InitialContext(env); /** * Lookup the Cart home object. The reference should be retrieved from the * application-local context (java:comp/env, the variable is * specified in the assembly descriptor; META-INF/application-client.xml) * but for simplicity this example uses a global variable. */ System.out.println("Context = " + context); Object homeObject = context.lookup("MyCart"); Hashtable env1 = new Hashtable(); env1.put("java.naming.factory.initial",
"com.evermind.server.rmi.RMIInitialContextFactory"); env1.put("java.naming.provider.url","ormi://localhost/ejbsamples1"); env1.put("java.naming.security.principal","admin"); env1.put("java.naming.security.credentials","welcome"); Context context1 = new InitialContext(env1); Object homeObject1 = context1.lookup("MyProduct"); System.out.println("HomeObject1 = " + homeObject1);

Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index