Oracle9iAS Containers for J2EE Services Guide Release 2 (9.0.2) Part Number A95879-01 |
|
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:
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.
Central to JNDI is the concept of the initial context. The two most often-used JNDI operations in J2EE applications are:
InitialContext
object.
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 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
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:
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 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:
See "Remote Client Example" for a code example that sets these properties and gets a new JNDI initial context.
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.
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.
ApplicationClientInitialContextFactory
invokes RMIInitialContextFactory
to read the following properties from the environment:
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
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.
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.
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 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).
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:
application-client.xml
file.
http://www.orionserver.com/docs/remote-access/remote-access.xml
The RMIInitialContextFactory
uses the same environment properties that are used by ApplicationClientInitialContextFactory
, namely:
dedicated.connection
java.naming.provider.url
http.tunnel.path
SECURITY_PRINCIPAL
SECURITY_CREDENTIALS
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);
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|