Oracle9iAS Containers for J2EE Services Guide Release 2 (9.0.3) Part Number A97690-01 |
|
This chapter describes the Java Naming and Directory Interface (JNDI) service implemented by Oracle9iAS Containers for J2EE (OC4J) applications. It covers the following topics:
JNDI, part of the J2EE specification, and provides naming and directory functionality for Java applications. Because JNDI is defined independently of any specific naming or directory service implementation, 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
A JAR file implementing JNDI, 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, JMS services, local and remote EJBs, and many other J2EE objects and services.
The concept of the initial context is central to JNDI. The two most often-used JNDI operations in J2EE applications are:
InitialContext
object (in the javax.naming
package).
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.
The following example shows two lines of Java code to use 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 initial contexts for using JNDI, and 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
When OC4J starts up, it constructs a JNDI context for each application 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, define new values for properties, and 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 three places:
jndi.properties
file contained in the application EAR file (as part of application-client.jar
).
Hashtable
passed to the JNDI initial context constructor.
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 by OC4J when the server is started, using the default environment for that application. This constructor is the one typically used in code that runs on the server side, such as in a JSP, EJB, or servlet.
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, defined in the javax.naming.Context
interface, are listed in Table 2-1.
See "Remote Client Example" for a code example that sets these properties and gets a new JNDI initial context.
The three JNDI initial context factories available for use by application code. They are
The following sections describe each of these factories and their uses in OC4J applications.
When an application client needs to look up a resource that is available in a J2EE server application, the client uses ApplicationClientInitialContextFactory
in the com.evermind.server
package 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.
When clients use the ApplicationClientInitialContextFactory
to construct JNDI initial contexts, they 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.
ApplicationClientInitialContextFactory
invokes RMIInitialContextFactory
to read the properties listed in Table 2-2 from the environment.
Property | Meaning |
---|---|
|
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
|
|
The URL to use when looking for local or remote objects. The format is either Multiple hosts (for failover) can be supplied in a comma-separated list. |
|
Specifies an alternative |
|
The user name. Required in client-side code to authenticate the client. Not required for server-side code because authentication has already been done. |
|
The password. Required in client-side code to authenticate the client. Not required for server-side code because authentication has already been done. |
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 need not specify an InitialContextFactory
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.
When code is running in a server, it is, by definition, part of an application. Therefore, as part of an application, OC4J can establish defaults for properties that JNDI uses. For the java.naming.factory.initial
property, OC4J sets ApplicationInitialContextFactory
in the com.evermind.server
package 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 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 performed locally in the same virtual machine.
However, when you use the default ApplicationInitialContextFactory
, 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.
As a concrete example, consider a servlet that needs to get a data source to perform 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 necessary, because 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, because no URL is required to look up an object contained within the same application or under java:comp/
.
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).
Occasions arise for use of the RMIInitialContextFactory
property in the com.evermind.server.rmi
package. Using either the default server-side ApplicationInitialContextFactory
or specifying ApplicationClientInitialContextFactory
works for most application purposes.
In some cases, however, an additional context factory must be used:
application-client.xml
file.
http://www.orionserver.com/docs/remote-access/remote-access.xml
The RMIInitialContextFactory
uses the same environment properties used by ApplicationClientInitialContextFactory
--namely:
dedicated.connection
java.naming.provider.url
http.tunnel.path
SECURITY_PRINCIPAL
SECURITY_CREDENTIALS
You can use the following code 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);
|
![]() Copyright © 1996, 2002 Oracle Corporation. All Rights Reserved. |
|