Java Naming and Directory Interface (JNDI) is a naming service that allows a program or container to register a "popular" name that is bound to an object. When a program wishes to lookup a name, it contacts the naming server, through a well-known port, and provides the public name, perhaps with authorization information. The naming server returns the object or, in some cases, a stub that can be used to interact with the object.
In the discussion below, JNDI will be discussed as it is used with respect to WebSphere 5.0. A JNDI server runs as part of the WebSphere environment. When the container is initiated, it loads the various applications deployed within it. Part of that process involves opening their respective EAR files and, in turn, their JAR files. For EJB container objects, such as entity and session EJBs, they are registered with the local JNDI server. Their public names are derived from their deployment descriptors or as a default value based on the class name. Once the EJB container is operational, the objects within it will be available through the associated JNDI server.
The examples below illustrate different means for obtaining a stub for an EJB Home interface (recall that Home in this context refers to an interface to the container used to create or accesse an instance of an EJB). Note that the resources used to access an EJB's interfaces will differ according to whether it is a Local vs. Remote interface and according to whether the request comes from within the same host or from a remote host.
The examples are constructed as methods that return an instance of a Home interface.
Same Context: Local Home
To access an EJB's Local Home interface, you must first crate a reference to it. This is done in the execution thread in which it is called. This often means in the Session, even for an Entity EJB.
Go to the Deployment Descriptor for the appropriate Session EJB and select the Reference tab. Do the following:
Select the particular session ejb and click on the add button.
Specify EJB local reference and then Next.
Provide the following:
JNDI Name (e.g. ejb/ABTDLocalHome)
Link (Enterprise bean in another project: the one that has the bean to be reference),
Type: entity
Local home: select the fully qualified name of the Home interface
Local: specify the local bean interface (may have to copy from Local Home.
Save Deployment Desciptor and re-generate access beans and RMIC and Deploy classes (note: check that all your ejb classes are present, as seen in the EJB's Deployment Desciptor and, if not, add them).
private ABTDLocalHome getABTDLocalHome() {
ABTDLocalHome home = null;
InitialContext context;
try {
context = new InitialContext();
home = (ABTDLocalHome)context.lookup( "java:comp/env/ejb/ABTDLocalHome" );
} catch (NamingException e) {
System.out.println( "Naming Error in getABTDLocalHome.JNDI lookup: " + e.getMessage() );
return null;
}
return home;
}
Note: the java:comp/env/ prefix is not part of the JBDI name, per se, but rather a "signal" to JNDI that the name/path that follows is a special type of name -- a local reference -- that is to be evaluated differently form the way conventional JNDI names are handled. Note, also, that the resulting object is simply cast to its appropriate type in the conventional way. This is possible since all of the objects are conventional Java objects and the "connection" is a Java method call by reference.Same Host, Differenet Context: Remote Home
private ABTDHome getABTDRemoteHome() {
ABTDHome home = null;
InitialContext context;
try {
context = new InitialContext();
Object initialReference = context.lookup(
"ejb/jbs/ftob/ejb/td/ABTDHome" );
home = (ABTDHome)javax.rmi.PortableRemoteObject.narrow(
initialReference, ABTDHome.class );
} catch (NamingException e) {
System.out.println( "Naming Error in getABTDRemoteHome.JNDI lookup: " + e.getMessage() );
return null;
}
return home;
}
Note: unlike the Local Home Interface example, the reference to the Remote Home Interface is a conventional JNDI name that is generated by WSAD and is visible in the object's Deployment Desciptor. It is because WSAD generates a JNDI name to this interface, not the Local interface, that one must use the Reference form shown above. Note also, that the object obtained is a stub delivered through IIOP, a CORBA protocol used to support remote procedure calls. Consequently, it must be converted to a conventional Java object from its CORBA form; this is done through the process of narrowing.
Different Host: Remote Home
private ABTDHome getABTDRemoteHomeFromRemoteHost() {
ABTDHome home = null;
InitialContext context;
try {
Properties properties = new Properties();
properties.put( javax.naming.Context.PROVIDER_URL,
"IIOP://remote_host_ip_address:2809/" );
properties.put( javax.naming.Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.websphere.naming.WsnInitialContextFactory" );
context = new InitialContext( properties );
Object initialReference = context.lookup(
"ejb/jbs/ftob/ejb/td/ABTDHome" );
home = (ABTDHome)javax.rmi.PortableRemoteObject.narrow(
initialReference, ABTDHome.class );
} catch (NamingException e) {
System.out.println( "Naming Error in getABTDRemoteHome.JNDI lookup: " + e.getMessage() );
return null;
}
return home;
}
Note: The InitialContext is defined by Properties or environment variables. Included are the address of the remote JNDI server and a designation of an InitialContext Factory. The JNDI server is identified by the IIOP protocol prefix, followed by the IP address and port of the server. In the WebSphere Studio context, the JNDI server's properties can be seen in the ports tab of the WAS server deployment descriptor (its .wsi file). Its port is referred to as the ORB Boostrap Port, whose default port is 2809 but may be reset, especially if you are simultaneously running both WSAD and WAS on the same machine.Once the InitalContext object is obtained, processing is similar to that shown above for obtaining the Remote Home Interface on the same host.