If you are curious about EJB components or want to know how a sample Java enterprise application works, this article is for you. Knowledge of the Java programming language and a basic understanding of J2EE APIs and technology is assumed. Bean providers, application assemblers and deployers as specified by EJB 1.1, and developers migrating from WebSphere Application Server 3.5, might find this article useful as they migrate to WebSphere Application Server 4.0.
This sample project consists of an entity bean, a session bean, a sample servlet, and a sample client. The entity bean represents a table, EMPBEAN, in the database. The session bean is very simple and accesses the database directly using a pooled database connection. It also accesses the database using an entity bean. The sample servlet is an EJB client that outputs the results to the browser. There are some data wrapper classes and dependent classes in this project to demonstrate typical classpath issues in a real scenario (although their use is superfluous in this project). You can download a zip file with all the source code.
This section gives a high-level introduction to Java enterprise application programming using J2EE technology, and discusses how to select different types of beans for an enterprise application.
EJB components are a Java server-side component model based on distributed object technology. This model is very robust, flexible, and vendor-independent. It aids in rapid development of business objects (the middle tier) that can run in any EJB server (application server/container provider) with little or no change to the code. The EJB server provides primary services such as object distribution, naming, security, persistence, transaction management, and concurrency. Therefore, the application developer need only focus on coding the business logic without having to code the low-level services automatically handled by the container.
The two fundamental types of EJBs are entity beans, which represent persistent data, and session beans, which represent a workflow or a business process.
Because entity beans purely represent data, it is suggested that no workflow logic be coded in an entity bean. In most cases where an entity bean is necessary, a container-managed persistence (CMP) entity bean is the best choice because the container will generate database access code, and the EJB developer has the flexibility to change the DBMS or the Table layout without rewriting the bean. However, this choice can be limited by the deployment tool's limitation to map the bean instance's state to the database, in which case a bean-managed persistence (BMP) entity bean may be used.
Session beans are typically used to implement business logic and encapsulate entity beans. They expose an interface through which clients can access various services, or methods. A stateless session bean maintains no state across any two method calls (services it provides), whereas a stateful session bean maintains a state that is related to the client. A session bean can access data directly from the database or it can invoke methods on an entity bean to do the same. Making the correct choice between direct access and indirect access is often difficult.
A row in a database table should be modeled as an entity bean instance only if there is a requirement that a client frequently query/update/delete the rows. In this scenario, the overhead of maintaining an entity bean is justified, because it provides a safe and consistent data manipulation logic that can be reused in several workflows. Such an entity bean is encapsulated in a session bean only if:
- There are many such clients performing the updates, deletes, and queries in a specific way that is meaningful to the application. In this case, a session bean layered on top of an entity bean will ensure uniform and consistent data manipulation across the entire enterprise application. For example, an update to a column will always result in updating a flag (another column) in the same table or some other table. This logic in the session bean will force the clients to always do the right thing, ensuring consistency in the application and preventing code duplication at the client side.
- There is more than one entity bean that needs to be updated, deleted, or queried by a client in a workflow.
Every remote method call involves transferring data from the client EJB stub to the server and back to the client EJB stub generating network traffic. Network traffic and latency impact performance, especially in a large enterprise application where thousand of clients interact with the EJB server. By reducing the remote method calls, application performance can be improved. A session bean accessing multiple entity beans is much more efficient and easy to maintain than allowing clients to make multiple remote method calls.
Despite the many advantages of using entity beans, they're not always the best solution. They occupy more memory, consume more cycles of CPU, and are generally inefficient compared to stateless session beans. When just a query or a simple update to a database is needed, a session bean directly accessing the database is the right choice. When session beans access the database directly, the overall performance of the system will improve. Transaction requirements may also require session beans to have direct database access. Thus, sometimes a session bean should access a database directly and sometimes it should access the database through an entity bean.
This section discusses coding a session bean that manipulates data with two methods: indirectly accessing the database using a CMP entity bean, and directly accessing the database using a pooled database connection provided by the container. This section also includes:
- Using EJB references and resource references in EJB architecture
- CMP entity bean development
- Web application development
- A pure Java client accessing the EJB components directly
The CMP entity bean descriptions are:
- Remote interface is
com.entangle.entityejbs.EmpInterface - Primary key is
com.entangle.entityejbs.Empkey - Home interface is
com.entangle.entityejbs.EmpHome - Bean implementation is
com.entangle.entityejbs.EmpBean
The Emp bean instance represents a row in the database table; EmpBean is the name of the table and it is generated by the deployment tool. The Emp bean has the following properties:
/**All of these are container managed fields They represent columns in the database table */ public String firstName; public int id; public String job; public String lastName; public double salary; |
In this bean class most of the methods, other than the EJB call back methods, are accessors and setters for the above properties. However, there is one business method that has a return type of EmployeeRec, as follows.
/**This method returns a wrapper object that has all the
properties of the bean class. This is more efficient than
using accessors for each property */
public EmployeeRec getEmployeeRec() {
return new EmployeeRec(id, firstName, lastName, job, salary);
}
|
None of the methods in the implementation throw a RemoteException. The EJB 1.1 specification introduced EJBException (a RuntimeException), which must be thrown to indicate that a system exception, or non-application exception, has occurred and the current transaction, if any, needs to be rolled back. The method ejbCreate() is defined to return a primary key instead of void.
The Emp bean's remote interface simply defines the implemented business methods and the home interfaces define home methods as described by the EJB 1.1 specification.
The session bean, first method
The sample session bean is a stateless session bean and has two bean methods. The first method, findEmployeeRec, takes an argument and simply invokes a method on the entity bean to get the EmployeeRec wrapper type. This method looks up the JNDIREFNAMES.EMP through the context object. JNDIREFNAMES is a utility class that holds the values of various types of references.
Assigning JNDI names to beans is the responsibility of the deployer, not the bean developer. As a bean provider, there is no way of knowing the true JNDI name of an external resource (another EJB, datasource, environment value, and so on) unless the bean provider is also assuming the role of assembler and deployer.
In the EJB 1.1 specification, the concept of JNDI Environment Naming Context (JNDI ENC) was introduced as a part of the container-bean contract. The container is required to provide a naming context of java:comp/env to every bean and the naming context must be unique to a bean type. There is a possibility that two beans can look up the same string java:comp/env/ejb/myejb in their context and obtain different types of objects that are bound in the global JNDI naming context.
Using java:comp/env namespace within the enterprise bean lets the bean locate external information without prior knowledge of how the external information is named and organized in the target operational environment. Using this naming context will not tie up a bean with the JNDI name of a resource that is known only at the time of deployment.
The EJB 1.1 specification recommends (but doesn't require) that all EJB references be organized in the EJB subcontext of the bean's environment. In the code sample, the value of JNDIREFNAMES.EMP is set to java:comp/env/ejb/EmpBean.
/** This method is layered on the top of the entity bean. This is just a
very simple method that invokes a method on the entity bean. The value of
EMP is java:comp/env/ejb/EmpBean. */
public EmployeeRec findEmployeeRec(int id)
{
Context ctx = null;
EmployeeRec empRec = null;
try
{
ctx = new InitialContext();
Object obj = ctx.lookup(JNDIREFNAMES.EMP);
EmpHome empHome = (EmpHome)
PortableRemoteObject.narrow(obj, EmpHome.class);
........
........
}
|
The session bean, second method
The second method demonstrates accessing the database directly using a pooled database connection. Before an enterprise bean can access a pooled database connection, a datasource must have been created and configured in the server environment. The bean method looks for a JNDIREFNAMES.SAMPLEJDBC in the context. The value of this variable is java:comp/env/jdbc/sample. This is a logical name that can be bound to a JNDI datasource object during the deployment phase. You don't need to know the actual JNDI name when you code the enterprise bean.
/** This method in the session bean directly accesses the database
taking advantage of the jdbc database connection pool maintained
by the Application Server Environment.
The value of SAMPLEJDBC is "java:comp/env/jdbc/sample"
The value of SELECT_FROM_EMP is
"select firstnme from employee where empno = ?";
*/
public String getEmployeeName(String empno)
{
Context ctx = null;
DataSource ds = null;
Connection conn = null;
PreparedStatement ps = null;
ResultSet result = null;
String empName = null;
System.out.println("AccessDataBean: getEmployeeName for: " + empno);
try
{
ctx = new InitialContext();
ds = (DataSource) ctx.lookup(JNDIREFNAMES.SAMPLEJDBC);
conn = ds.getConnection();
ps = conn.prepareStatement(AllSqlStatements.SELECT_FROM_EMP);
.......
.......
}
|
To successfully execute this method, the database or schema name referenced by the datasource must contain a table named "employee" whose column names must include "firstname" and "empno." The default sample DB2 UDB database meets this criteria.
The sample Web application project has just one servlet (com.entagle.sampleservlets.AccessServlet) and one HTML file. The servlet looks up the session bean using an EJB reference. The Web application has one servlet mapping "getdata" that refers to AccessServlet. The context root of the application is set to /data. EnterInput.html is added to the resource files of the WAR file, and is also the welcome file for the application. Welcome files are entry points to the application that help to complete the URL. For example, when the user requests http://<hostname>/data/, the Web server redirects it to http://<hostname>/data/EnterInput.html.
If the servlet were to access the database directly, the code would be very similar to the code in the session bean above. In this case, the servlet looks up the EJB and makes remote method calls to manipulate the data as follows.
/** This method looks up the enterprise bean (session bean) using a
Java:comp/env/ejb/AccessDataBean (Value of ACCESSDATAEJB)
*/
public void doGet( HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException
{
......
......
try
{
Context ctx = new InitialContext();
Object obj = ctx.lookup(JNDIREFNAMES.ACCESSDATAEJB);
AccessDataHome home =
(AccessDataHome) PortableRemoteObject.narrow(obj,
AccessDataHome.class);
......
......
}
|
Pure Java clients (standalone Java applications) can also access EJB components. These clients use RMI/IIOP to talk to the application server environment. WebSphere Application Server 4.0 ships with a J2EE client container that you can use to access EJBs, and provides a J2EE environment so clients can access the java:comp/env name space. There is an XML deployment descriptor for every J2EE client (per the EJB 1.1 specification), which maps all types of references to the appropriate JNDI names. The launchclient.bat that comes with version 4.0 is a convenient command line utility you can use to run a J2EE Java client.
The java command can also be used to run the standalone Java application that accesses the EJBs. However, all resources accessed using Context.lookup in the code must specify the true JNDI name. These include the usertransaction object, various types of resource factories, EJBs, and so on. There is no need for any deployment descriptor in this case. All necessary JAR files must be in the classpath (operating system environment variable) or must be specified on the java command line. The sample project discusses a J2EE client of this type.
This section discusses the configurations needed to successfully run an enterprise application in WebSphere Application Server 4.0. Configuration includes design considerations such as:
- Where to put a dependent class
- What to include in an EJB jar file
- How to set up the classpath for the EAR file, AAT, SEAppInstall tool, and administration console
The sample project has the following classes:
| Class | Location |
| stateful session bean | In com.entangle.sessionejbs package: AccessData (Remote Interface), AccessDataHome (Home Interface), and AccessDataBean (Implementation class). |
| CMP Entity bean | In com.entangle.entityejbs package: EmpInterface (Remote Interface), EmpHome (Home Interface), EmpKey (Primary key class) and EmpBean (Implementation class). |
| common | Used across entity EJBs and session EJBs belonging to this enterprise application, are in com.entangle.common package: EmployeeRec (A wrapper class). Archived in commonclasses.jar file. |
| SQL helper | In com.entangle.sql package is AllSqlStatements. Archived in sqlclasses.jar file. |
| utility | Potentially common across multiple EAR files, are in com.entangle.util package. They are JNDIRefNames (store for all the EJB references, resource references, etc.) and FullName. Archived in utilclasses.jar file. |
With classpaths you have to make an important decision: Where is the best place to put the various JAR files containing the dependent classes? In our sample project, the commonclasses.jar, sqlclasses.jar, and utilclasses.jar files are necessary for the application to run properly. Dependent JAR files can be specified in different ways.
One way to specify dependent JAR files is to put them at the very top level of the EAR file and specify it in the classpath of the EJB module/WAR module. This decision should be based on whether or not the dependent class JAR files are an integral part of the EAR file/enterprise application. In this sample project, the commonclasses.jar and sqlclasses.jar files are an integral part of this enterprise application because they are not shared among multiple enterprise applications. Therefore, the commonclasses.jar and sqlclasses.jar files are placed in the EAR file. See Figure 1 for more details.
Figure 1 below shows that commonclasses.jar and sqlclasses.jar are placed at the very top level in the EAR file. Files can be added in this area by selecting the Files node and then selecting Add from the right mouse-click menu.
Figure 1. commonclasses.jar and sqlclasses.jar files

Another way to specify dependent JAR files is to put them in the dependent class path and the Java virtual machine (JVM) classpath. The utilclasses.jar file in the sample is assumed to be shared by multiple enterprise applications/EARs, so this JAR file is placed in the dependent classpath during the deployment phase, and is also placed under the JVM classpath. See Figure 2 and Figure 3 for details. The JVM classpath is set to ensure runtime recognition of class files in utilclasses.jar.
Figure 2 shows how to set the dependent classpath during generation of deployment code.
Figure 2. Setting the depedendent classpath

Figure 3 shows where to set the application server's JVM classpath. This must include the utilclasses.jar file so the application server will find the required class at run time.
Figure 3. Setting the JVM classpath

In the classpath for either the EJB module or WAR module, the JAR files must be separated by spaces as shown in Figure 4 and Figure 5.
Figure 4 shows that the classpath is set by separating the JAR files with a space in the EJB JAR module. This classpath will be in the manifest file of the EJB JAR file.
Figure 4. Setting a classpath

Because the commonclasses.jar file is also shared by the WAR module, it must be placed in the WAR module classpath. In addition to any dependent JAR files, the EJB JAR file must be placed in the Webmodule classpath since one of the Web components accesses an EJB. See Figure 5 for details.
Figure 5 shows the classpath setting of the Web module. The EntangleApp5.jar (EJB JAR file ) and commonclasses.jar files are separated with spaces. The Context root for the Web module is set to /data.
Figure 5. Classpath setting of the Web module

Features of the Application Assembly Tool (AAT)
The AAT uses Java's reflection APIs to probe the remote interface and home interface classes. If the tool does not find a class that is either a parameter or a return type to one of the methods belonging to the remote or home interface, the tool cannot display that method (containing the unknown class as an argument or the return type) in the "Method Extensions" node under that particular EJB. So, deployment descriptor properties such as isolation levels, access intent, security, method permissions, and so on cannot be set for such problem methods.
In the Create new bean dialog of the AAT, if you select the home interface using the Browse button, the remote interface and the bean class are automatically filled in. Even if those names match with the correct remote interface and the bean class, these files must be browsed again. This ensures that the AAT copies the files in the EJB JAR file.
When the AAT generates deployment code, it looks for the dependent classes in three places:
- The classpath of the
javacommand in the batch file that starts AAT (-classpath command line argument). - The classpath of the EJB JAR module or the Web module (Figure 4 and Figure 5).
- The dependent classpath specified during deployment (Figure 2).
In the sample project, the class FullName is in utilclasses.jar and is also the return type of one of the remote methods in EmpInterface EJB. This class serves no purpose other than to demonstrate a classpath issue.
/** The method getFullName() is in the remote interface */
package com.entangle.entityejbs;
import com.entangle.common.*;
import java.rmi.*;
import javax.ejb.*;
import com.entangle.util.*;
public interface EmpInterface extends javax.ejb.EJBObject
{
......
......
/** This method returns a dependent class FullName that is
in the package com.entangle.util */
public FullName getFullName() throws RemoteException;
......
......
}
|
In the sample project, to ensure that AAT finds the class FullName, the utilclasses.jar file is specified in the classpath of the Java program that started the AAT (number 1 in the list above). If this class is not specified in the classpath command line argument of the Java program, the following error appears in the command window that started the AAT:
Could not reflect methods for com.entangle.entityejbs.EmpBean because one of the classes could not be loaded. Com/entangle/util/FullName. Note that the error will occur even if the utilclasses.jar file is placed in the EAR file and the classpath for the EJB JAR file is set. The key point to remember is that the classpath specified in the EJB JAR file or the Web module is not effective until the deployment phase.
If an unknown class is referenced only in the implementation class (the bean class of the EJB) either as a return object or in the code, the AAT tool does not check for this class. Such unknown classes are checked at run time by the application server and must be placed in the JVM settings of the application server (Figure 3).
If the unknown class is in the remote interface and the AAT does not find the class either in the classpath command line of AAT or in the EAR file classpath, the tool will report an error (RMIC Failed) during generation of deployment code.
The workaround for this problem would be to include the FullName class in the Files node under the EJB JAR file. However, doing so does not fit the current design of our sample code. (Remember that utilclasses.jar could be used in multiple Enterprise Applications by design. Moreover, doing that involves undoing the archive.)
Installing with SEAppInstall and Web Administrators Console
The administrators console installation process will not allow reinstalling the application. To reinstall an application, the server must be started twice -- once after uninstalling and once after installing. On the other hand, the SEAppInstall command line will allow reinstallation of the application.
After installation using the administrators console, the configuration must be saved and the plugin configuration must be regenerated. Plugin information can be regenerated by selecting Nodes> <hostname>>Application Servers>Default Server, and following the instructions. Plugin information is dynamically generated and no server restart is necessary.
SEAppInstall will save the server configuration, but the plugin must be regenerated. You can use the command line script GenPluginCfg.bat to regenerate the plugin information. If SEAppInstall is used to generate the deployed code for the sample project, ensure that the classpath of the Java program that starts SEAppInstall includes the utilclasses.jar file.
The following is the code sample for a simple Java client that accesses the Emp bean. Notice that the actual JNDI name is used instead of java:comp/env. This is necessary when the Java client is run outside of the J2EE client container.
/* Make sure that PROVIDER_URL, JNDI name has been changed
to match the real IP and the global
JNDI name of the EMPBEAN */
package com.entangle.javaclient;
...........
public class EmpClient
{
public static EmpInterface getEJB()
{
Properties prop = new Properties();
Prop.put(javax.naming.Context.PROVIDER_URL,
"iiop://<Real IP >:900/");
.....
.....
Object obj = ctx.lookup("<JNDI NAME OF EMPBEAN>");
......
}
|
This Java client application class can also be included in the J2EE module (EAR File), in which case logical names (references) can be used. The launchClient.bat script will provide the J2EE client environment and can be used to execute the Java client application that is inside an EAR file.
WebSphere Application Server 4.0 Advanced Edition, along with tools such as AAT and SEAppInstall, facilitates rapid development of scalable and fault-tolerant J2EE applications. J2EE is a very robust and popular standard for multi-tier enterprise applications. Application Server goes beyond J2EE 1.2.1 certification and therefore supports the latest Java server technology. Understanding the new tools and the new features of J2EE 1.2.1 architecture will help you harness the powerful features of WebSphere Application Server.
| Name | Size | Download method |
|---|---|---|
| ejbpaper.zip | HTTP |
Information about download methods
- Download the source code and the working example of the sample project discussed in this article.
- You can find more information on EJB architecture in the EJB 1.1 specification on Sun's site.
- Get more details about developing J2EE applications using WebSphere Application Server 4.0 AEs at WebSphere InfoCenter.
- Learn how to deploy an EJB application created using VisualAge for Java 4.0 and WebSphere Studio 4.0 to WebSphere Application Server 4.0.
- Explore EJB metadata in WebSphere 4.0.
Shiva Nistala is a Senior Java Consultant with Adea Group and currently works for IBM WebSphere Developer Relations. He is on the technical support team and provides support to Enterprise Application (J2EE) designers and developers working with WebSphere technologies. You can reach Shiva at snistala@us.ibm.com.
