Introduction of best practice.
This best practice applies to the following product, version, and plaform:
- WebSphere Studio Application Developer, version 4.0.x, for Linux and Windows
- WebSphere Application Server - Base, version 4.0.x, for OS/390, zSeries, AIX, HP-UX, Solaris,Linux and Windows
One of the difficulties in developing and deploying EJBs written to the EJB 1.0 specification level was dealing with the JNDI name of the EJB home. For example, a great deal of code was written, as in the following code snippet from a session bean attempting to lookup the home of the com.ibm.wsc.Bean2 EJB:
Context myInitCtx = new InitialContext();
Object result = myInitCtx.lookup("com/ibm/wsc/Bean2Home");
com.ibm.wsc.Bean2Home theBean2Home =(com.ibm.wsc.Bean2Home)
javax.rmi.PortableRemote.narrow(result,com.ibm.wsc.Bean2Home.class); |
This technique worked well in the development tooling and seemed to work okay in the deployment phase of the application. One could look at the code and determine the JNDI name given to Bean2Home in the namespace, as it is merely the EJB Home interface name. The coding convention was pretty straightforward as the EJB class name was used to construct the code to locate the home.
The problem arises when "Bean2" was deployed into two different servers using the same (shared) JNDI namespace.
For example, one could have two servers, WSQASV and WSFXSV, sharing the same namespace (i.e., LDAP or CosNaming server) and desire to deploy the same J2EE application (i.e., .ear file) in both servers. This presents a problem as the session bean in each server must find/use the correct instance of Bean2Home. To avoid the problem, there are two things which must be done:
- The JNDI name for the Bean2Home installed in server WSQASRV must be different from the JNDI name of the Bean2Home installed in server WSFXSV. The JNDI names must be different for the lookup( ) of the EJB home to return a reference (i.e., IOR) to the correct server where the EJB is installed.
- The client (i.e., session bean) referencing Bean2Home must explicitly specify the JNDI name of the Bean2Home depending on the server in which the application is deployed.
The naming scheme for EJBs already developed and the practice of hardcoding the JNDI name into the java source is the real cause of the problem. There is the need to provide runtime-specific information without having to modify the code depending on the server into which an EJB is deployed. The result is the creation and implementation of a scheme which utilizes ResourceBundles or Properties files to provide runtime information, as in the following code snippet:
ResourceBundle myRB = ResourceBundle.getBundle("ServerProps");
String myBean2HomeJNDIName = myRB.getString("Bean2HomeName")
Context myInitCtx = new InitialContext();
Object result = myInitCtx.lookup(myBean2HomeJNDIName);
com.ibm.wsc.Bean2Home theBean2Home =(com.ibm.wsc.Bean2Home)
javax.rmi.PortableRemote.narrow(result,com.ibm.wsc.Bean2Home.class); |
All that is required with this technique is to create a unique .properties
file named ServerProps.properties which contains something like the
following for the WSQASV server:
Bean2HomeName=WSQASV/com/ibm/wsc/Bean2Home
The ServerProps.properties file for the WSFXSV server contains something
like:
Bean2HomeName=WSFXSV/com/ibm/wsc/Bean2Home
We now have a scheme which doesn't require a change to the java code prior to be deployment into either server, and the naming convention for the EJB home is somewhat preserved but is server qualified. This "server name" qualification will allow Bean2Home to be located correctly in either server. During the deployment phase, the deployer only needs to know the contents of the .properties files to assign the correct JNDI names to the EJBs.
This technique leaves the deployer with only one problem left to solve: how to manage the server-specific .properties files. The quandary is that the .properties file is both application-specific (i.e., a specific EJB home contained in the application is being looked up) and server-specific (i.e., the JNDI name of the EJB home is dependent on the server into which the application is installed). The question is: Does the ServerProps.properties file belong in the J2EE application package (i.e., .ear file) or in the classpath of the server? Placing the .properties file in the .ear file means the .ear file must be modified prior to deployment into the two servers. This is not desirable for the same reason modifying the java source code is not desirable. However, it is very desirable to have a single bundle of parts and not have to specifically configure the server for application-specific files.
Fortunately, the EJB 1.1 specification introduced JNDI enhancements, specifically the environment naming context (ENC), and strong recommendations as to how EJBs, resources and application-specific environment variables should be "found". Refer to Chapter 14 of the EJB 1.1 specification and Chapter 5 of the J2EE 1.2 specification for details. The following code snippet uses the recommended java:comp/env construct to lookup the Bean2Home:
Context myInitCtx = new InitialContext();
Object result = myInitCtx.lookup("java:comp/env/ejb/Bean2Home");
com.ibm.wsc.Bean2Home theBean2Home =(com.ibm.wsc.Bean2Home)
javax.rmi.PortableRemote.narrow(result,com.ibm.wsc.Bean2Home.class); |
The magic of associating the "java:comp/env/ejb/Bean2Home" string to a the JNDI name for Bean2Home residing in a specific server is left to the assembler and the deployer of the application. The application developer doesn't know or care about the JNDI name for the Bean2Home.
Specifically, the assembler must include a clause in the ejb-jar.xml file of the referencing EJB (or the web.xml file of the referencing servlet) with the following contents:
<ejb-ref> <ejb-ref-name>ejb/Bean2Home</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>com.ibm.wsc.Bean2Home</home> <remote>com.ibm.wsc.Bean2</remote> <ejb-link>Bean2</ejb-link> </ejb-ref> |
The .xml file contents will normally be built and validated by either the development tool (i.e. WebSphere Studio Application Developer) or the assembly tool (i.e., Application Assembly tool (AAT)) and not require hand construction. Notice that there is no JNDI name present, just a statement that this EJB (or servlet) is going to look up an EJB home of a given type, and that the EJB home resides in this J2EE application package or .ear file. (If the ejb-link descriptor is omitted, the servlet or EJB could look up and use a Bean2Home residing in any server having this bean type residing in the JNDI name space.) Actually the application assembler doesn't know or care about the JNDI name for the Bean2Home. The assignment of the JNDI name is left to the deployer, with the constraint that the Bean2Home reside in this J2EE application in whatever server it is deployed.
During the installation/deployment of the application in a specific server (e.g., into either the WSQAEV or WSFXSV servers in our example), the deployer must perform two tasks:
- Create a JNDI Name for the Bean2Home which refers to the Bean2Home being installed in "this" server. The JNDI name must be unique in the namespace to be able to locate the desired Bean2Home in "this" server and not inadvertently use a Bean2Home in some other server.
- Resolve the EJB reference to the correct Bean2Home JNDI name. Using the ejb-link descriptor forces the reference be resolved to the Bean2Home JNDI name in "this" server. Note that if the ejb-link had been omitted the ejb-ref could be resolved to the JNDI name of another deployment of Bean2Home in some other server.
The key points are:
- The application (and hence the application developer) does not require knowledge of the actual JNDI name of any component residing in this server or any other server which is registered in a common name space.
- There are no side files used by the application to use the correct JNDI names of EJBs depending on the server in which the components are deployed.
- There was no requirement to change files or deployment descriptors in the J2EE package (i.e., .ear file). A single unmodified, untailored .ear file can be deployed in any server.
This technique greatly enhances the portability of EJBs. Applications can be deployed quite easily without having to be concerned over the real JNDI name. An EJB can be extracted from one J2EE application and easily integrated into a different J2EE application.
The question remaining is: What JNDI name should be chosen by the deployer? The requirements are:
- The JNDI name of a component should be unique in the name space for the server into which the J2EE application is being deployed.
- The naming scheme should be manageable, if not self managing.
The Systems Management Administration tool for WebSphere for z/OS will allow the deployer to assign a designated JNDI name if he chooses to do so, or if the application requires it. This condition occurs when the lookup( ) is done without using the java:comp/env technique. More importantly, the administration tool will allow the deployer to assign a system-generated name which will be unique. The name has the following format:
<sysplex_name>/<server_name>/<application_name>/<module_name>/<component_name>/<class_name> |
Thus if Bean2 resides in the EntityBeans.jar file and all the J2EE components are packaged in BeanSalad.ear and the .ear file is to be deployed in the WSFXSV server on the WebSphere node/cluster associated with the WSCPLEX sysplex, the generated name would be:
WSCPLEX/WSFXSV/BeanSalad/EntityBeans/Bean2/com.ibm.wsc.Bean2Home.class
This name uniquely identifies the Bean2Home residing WSFXSV server on node WSCPLEX as opposed to the Bean2Home residing in the WSQASV server in this node.
Using this technique, we have achieved self-managed JNDI name uniqueness, unbeknownst to the application, and application portability at the .ear file deployment level (without a need to make changes to code or deployment descriptors and without additional side files).
The only alternative to using java:comp/env is to continue using the previously discussed EJB 1.0 techniques. While this technique continues to work, using the prescribed recommendation solves many of the technical issues.





