The concepts behind Enterprise JavaBeans (EJB) are not new, but they may appear daunting. Situated within their own tier of the Java 2 Enterprise Edition (J2EE) specification, EJB components tie the presentation layer of an application to back-end enterprise information systems, such as databases or mainframes. EJB architecture utilizes functionality from both EJB objects and the environment in which they run.
The why of EJB
Conceptually, EJB objects encapsulate business objects and concepts, letting developers concentrate on the details of solutions. From a design standpoint, EJB should incorporate portability and interplay. This arrangement allows a single EJB, whether developed in-house or by a third party, to work with multiple applications. For example, a customer relationship management (CRM) tool as well as an e-commerce application may use an EJB representing a customer. Configuration of these already adaptive objects becomes easier with deployment descriptors, XML files describing the EJB. Deployment descriptors allow modifying EJB properties and behavior without recompiling.
The where of EJB
EJB objects reside in the EJB container, an environment providing a wealth of services to developers. Depending on configuration, a container may handle security, transactions, and instance management. By removing these tasks from programmers, development time significantly decreases.
A distinction exists between J2EE servers and EJB containers—an EJB container may be part of a J2EE server, but it’s not mandatory. As part of a J2EE server, EJB clients usually take the form of Java servlets or Java Server Pages. However, freed from the dependence on the Web tier of J2EE, standalone EJB containers service requests from many types of clients, applications written in Java or other languages. Communication with the EJB container is the only prerequisite for a client.
The what of EJB
EJB objects fall into three categories:
- · Session Beans
- · Entity Beans
- · Message Driven Beans
Depending on required bean behavior, certain characteristics determine which type to use.
Session Beans act on a session-by-session basis. After a client requests and receives bean functionality, the session with that particular bean ends, leaving no record of what occurred. Session Bean types further divide, acting in a stateless or a stateful manner.
Stateless Session Beans have no knowledge of the client or any semblance of context regarding the request, making them ideal for one-off use. An example of this would be in a bug-tracking system where the user searches for all open bugs. The client application contacts a Stateless Session Bean, passing the search parameters. In turn, the bean accesses a database, selects entries matching the criteria, and passes records back to the client. When communication completes, the bean retains no recollection of the interaction. Because of this behavior, multiple distinct clients may simultaneously access a Stateless Session Bean with no ill effect.
In contrast, Stateful Session Beans associate requests with a specific client, joining client and bean in a one-to-one relationship. A shopping cart bean provides the quintessential example of this. The user performs the standard e-commerce tasks of adding products to the cart, entering address information, and placing the order. The cart bean maintains state and thereby knowledge of all these variables, associating them with a single client.
Entity Beans represent business objects or data that persist after a session ends. They often exist as single records in a database, but storage may take place in another medium, such as a file. An object representing a user—name, contact information, language choice—typifies Entity Bean use. Essential to persistence, the unique identity or primary key of an Entity Bean allows recognition and retrieval of the correct information for the correct object. Entity beans require a primary key “helper class” encapsulating the unique identifier of the object.
The previous bean types provide services to EJB clients in a synchronous manner. The client makes a request and then waits for a result from the bean. Message Driven Beans avoid this potential bottleneck. Using the Java Messaging Service (JMS), a client produces a message and publishes it to a message queue. A Message Driven Bean then consumes, or retrieves, the message, acting on its contents. In this way, communication of events or data becomes asynchronous; neither client nor bean needs to depend on direct response from the other.
For instance, a bank official in London uses an application to publish a message with the latest currency conversion rates. A foreign exchange bean deployed in Boston takes this information from the queue and updates a record in a database. Ideally, the Message Driven Bean passes the information to an Entity Bean handling the database transaction. In this way, each bean forwards tasks it cannot act on to a bean that can—a facade pattern—creating a true distributed component architecture.
The how of EJB
Regardless of category, three essential classes make up an EJB object: a home interface, a remote interface, and the bean implementation. A client application locates the home interface of a bean by use of the Java Naming and Directory Interface (JNDI). The home interface then returns an instance of the remote interface, exposing necessary bean implementation methods. The client calls these methods as it sees fit. The source code in Listing A better illustrates how the pieces fit together.
Depending on the type of bean, you may need to implement other methods. For instance, if a client needs to locate an Entity Bean, your Home interface will include a findByPrimaryKey() method that takes the primary key class as an argument, returning the proper object.
As mentioned earlier, deployment descriptors packaged with each EJB object tell the EJB container how this object should behave. One of these, called ejb-jar.xml, would describe the above—a Stateless Session Bean with container-managed transactions on all methods, as shown in Listing B.
Depending on the EJB container, another deployment descriptor tells the container how to identify and locate the bean using JNDI. In the case of a WebLogic server, this file, called weblogic-ejb-jar.xml, looks something like Listing C.
Bad news and good news
EJB use involves some inherent risks and potential problems. Programmers must adhere to the numerous syntactical and behavioral rules for coding EJB objects. They must also decide between persistence managed by the bean itself or by the EJB container; the wrong choice could lead to lost data. The potential for the container to crash exists, destroying active Session Beans. The container may also fail when attempting to roll back a transaction, losing information. Deploying EJB objects turns tedious with repetition, and debugging without the container source code hovers near impossible.
However, the component nature of EJB lends itself to code reuse, saving time and money in the long run. Developers focus on the business logic, placing the onus of security and transaction rollback on the EJB container. Reliable object instance management and ease of configuration add to the merits of EJB. While learning the design rules of Enterprise JavaBeans takes time and effort, the architecture yields significant bonuses when used in application development.
Serving up beans
Enterprise JavaBeans should make programming easier once you get the hang of them. Has this been true for you? Tell us about it or post a comment below.