It's essential for an app to have a strong infrastructure that enables app code to concentrate on addressing business problems without the distraction of handling "plumbing". This is why we choose to use J2EE; why we may choose to use EJB if we would otherwise need to write unduly complex code; and why adequate infrastructure classes are almost as important as an app server. We usually need to build some infrastructure ourselves, but it's generally best to use existing infrastructure where it's an option. Unfortunately there are no standards relating to infrastructure that simplifies the use of J2EE. Thus the choice will vary between projects. Possible sources of infrastructure include:

In this chapter we'll look at the issue of infrastructure primarily through examining the support packages used in the sample app. This code — which is based on my experience of successful approaches in several real projects — illustrates some of the major issues and provides a simple solution to problems that I haven't seen well-addressed elsewhere. The source code of all the classes discussed and the supporting classes is included in the download with this tutorial, so it can be used as a basis for your apps.


Emphasis on supporting infrastructure is a major difference between my approach in this tutorial and much J2EE literature. Most J2EE tutorials concentrate on J2EE APIs, rather than the reality of using them. Hence they tend to show quick and dirty approaches (for example, compromising correct error handling), or neglect productivity and maintainability considerations.

In this tutorial, I'm trying to demonstrate the use of J2EE to meet business requirements, rather than as an end in itself. As a bonus, this means that the download accompanying this tutorial includes much code that you can either use directly in your apps or use as the basis for your own code.

The approach discussed in this chapter is just one of many approaches for structuring J2EE apps. However, I've found the principles behind it to deliver high productivity and quality solutions in several real projects. The problems this infrastructure addresses and serves to illustrate are relevant to all J2EE apps.

Goals of a Strong Infrastructure

Using a strong standard infrastructure can deliver better apps, faster. A strong infrastructure makes this possible by achieving the following goals:

Essentially we're going to use standard infrastructure to help achieve the goals that we identified in . It's important that infrastructure isn't web-centric, even if we're developing a web app. This makes apps unnecessarily hard to test and dependent on one particular user interface. Thus infrastructure should not be limited to a web framework such as Struts (although such web frameworks are valuable, if used correctly). It's not enough to get business logic out of presentation layer artifacts such as JSP pages: business logic shouldn't be in web-specific classes at all. For examples, a Struts Action class is tied to the Servlet API. This makes Struts actions a poor place for business logic, which doesn't depend on the Servlet API. Thus while it is important to use a web app framework, the web-tier should remain a thin layer over a distinct business logic layer. Infrastructure will often take the form of frameworks, rather than class libraries. Often inversion of control is essential to conceal complexity from app code. We saw the benefits of this approach with JDBC in . A framework should be extensible. Although a well-designed framework will meet most requirements out of the box, it will fail unless it can be extended to meet unforeseen requirements. Use of interfaces within the framework will help to achieve this goal. A framework should be easy to use. Unduly complex frameworks will be ignored by developers, and create problems of their own. Irrelevant, or seldom-used, capabilities are a key danger. The Pareto Principle is particularly relevant to framework design. Often it's best to settle for a simple solution to most problems than a comprehensive, but complex solution that makes many tasks harder than they should be (J2EE itself arguably falls into the latter category).

Let's consider the core infrastructure used in the sample app. Like most successful infrastructures, the infrastructure described here is layered. When using it we can choose from different levels of abstraction, each building on lower-level components.

Using a Framework to Configure app Components

Let's begin by addressing the goals of externalizing configuration and facilitating the use of OO design.

The Problem

It's vital to adopt consistent practices in app configuration. While externalizing configuration (getting it out of Java code) is essential to parameterize apps, it's difficult to achieve without supporting infrastructure. Without such infrastructure, configuration management is usually haphazard. J2EE apps often hold configuration in a variety of formats, such as properties files, XML documents (an increasingly popular choice), EJB JAR and WAR development descriptors, and database tables. In large apps there is often little consistency in how configuration is managed. For example, property naming conventions (if there are any) may differ between developers and for different classes. More seriously, app classes are bloated by configuration management code irrelevant to their business responsibilities. Many app objects may read properties files or parse XML documents. Even if they use helper classes to simplify use of the underlying API, their business purpose is still obscured and they remain tied to the configuration format initially envisaged. Equally harmfully, without a central infrastructure for configuration management, app code is likely to use a variety of approaches to locating app objects. The Singleton design pattern is often overused, resulting in problems we'll discuss below. Alternatively, some app objects may be bound to JNDI or attached to the global ServletContext (in web apps), both of which approaches may complicate testing outside a JNDI server. Each app object is usually configured independently.


Generic, reusable infrastructures should be used to centralize configuration management and "wire up" apps in a consistent way. In this section we'll look at how the infrastructure used by the sample app uses JavaBean-based configuration, ensuring consistency throughout apps.

In this section we'll look at an app framework that centralizes configuration management and solves the problems we've just discussed.

Using JavaBeans

We discussed the benefits of JavaBeans in . For example, bean-based manipulation is excellent for applying configuration data held outside Java code, and performing "data binding", such as from HTTP requests onto Java object state.


If we make all app components JavaBeans, we maximize our ability to separate configuration data from app code. We also ensure that app components can be configured in a consistent way, wherever configuration data is held. Even if we don't know an app's class at run time (as opposed to the interfaces it implements), we know how to configure it if it is a JavaBean.

An object doesn't need to implement any special interfaces or extend a special superclass to be a simple JavaBean, exposing bean properties but not supporting bean events. All that is required is a no-argument constructor and property methods following a simple naming convention. Unlike EJBs, JavaBeans impose no run-time overhead. However, manipulating beans is more complex, and requires the use of reflection to instantiate objects and invoke methods by name. The core JavaBeans API does not provide the ability to perform some useful operations on beans, such as:

Since invoking methods by name and instantiating beans means handling exceptions from the core reflection package, error handling can also become cumbersome unless we use a higher level of abstraction.


The lowest layer of the framework used in the sample app is the com.interface21.beans package. This provides the ability to manipulate beans easily and adds the enhanced functionality described above, while respecting and avoiding duplicating the standard JavaBeans infrastructure.

The center of this package is the BeanWrapper interface and the default implementation, BeanWrapperImpl. A BeanWrapper object can be created given any JavaBean, and provides the ability to manipulate properties individually or in bulk and add listeners that will be notified when the bean is manipulated using the BeanWrapper. The most important methods in the BeanWrapper interface include:

 Object getPropertyValue (String propertyName) throws BeansException;

This returns a property value, given a string name following JavaBeans conventions. The string "age" would return a property exposed via a getAge() accessor method. However, all BeanWrapper methods also support nested properties to arbitrary depth: the string "spouse.age" would try to get the age property on the object value of the spouse property. This would even work if the declared type of the spouse property didn't expose an age property, but the current value did. The setPropertyValue() method is a parallel setter method with the following signature:

 void setPropertyValue (String propertyName, Object value)
 throws PropertyVetoException, BeansException;

This method throws the java.beans.PropertyVetoException to allow the use of event listeners to "veto" property changes, as described in the JavaBeans specification. The new value parameter can be converted from a string if necessary using the standard beans API PropertyEditor support (discussed below). Another setter method has the following signature:

 void setPropertyValue (PropertyValue pv)
 throws PropertyVetoException, BeansException;

This method is similar to the previous setPropertyValue() method, but takes a simple object holding the property name and value. This is necessary to allow combined property updates, performed by the following method:

 void setPropertyValues (PropertyValues pvs) throws BeansException;

This sets a number of properties in a single bulk update. The PropertyValues parameter contains multiple PropertyValue objects. Property setting continues on exceptions encountered attempting to set individual properties. Any exceptions are saved in a single exception, PropertyVetoExceptionsException, which is thrown once the entire operation is complete. Properties set successfully remain updated. Bulk property updates are useful in many situations, such as when populating JavaBeans from HTTP request parameters. The BeanWrapper interface includes convenience methods to find whether properties exist, such as:

 boolean isReadableProperty (String propertyName);

It is possible to obtain the object wrapped by a BeanWrapper using the following method:

 Object getWrappedInstance();

This enables us to move to ordinary Java invocation once bean manipulation is complete — for example, after initialization. It is possible to add and remove event listeners that implement standard JavaBeans interfaces using methods such as the following:

 void addPropertyChangeListener (PropertyChangeListener 1);
 void addVetoableChangeListener (VetoableChangeListener 1);

This means that, if a BeanWrapper is used to manipulate its bean properties, property change events will be fired even if a JavaBean being manipulated does not implement property change support. I took the important design decision to make the root of the beans package exception hierarchy, com.interface21.beans.BeansException, unchecked. As we usually use beans manipulation in initialization code, this is appropriate; failure to manipulate a named property will usually be fatal. However, it is still possible for app code to catch BeanExceptions if we choose. Several subclasses of BeanException are defined in the com.interface21.beans package, including:

Let's look at a simple example of using the BeanWrapper interface. TestBean is a concrete class that implements the interface ITestBean, which contains three properties: age(int),name(String), and spouse(Person), defined using normal JavaBeans naming conventions as follows:

 public interface ITestBean {
 int getAge();
 void setAge(int age);
 String getName();
 void setName(String name);
 ITestBean getSpouse();
 void setSpouse(ITestBean spouse);

By creating a new BeanWrapper object we can easily set and get property values:

 TestBean rod = new TestBean();
 BeanWrapper bw = new BeanWrapperImpl(rod);
 bw.setPropertyValue("age", new Integer(32));
 bw.setPropertyValue("name", "rod");
 bw.setPropertyValue("spouse", new TestBean());
 bw.setPropertyValue("", "kerry");
 bw.setPropertyValue("spouse.spouse", rod);
 Integer age = (Integer) bw.getPropertyValue("age");
 String name = (String) bw.getPropertyValue("name");
 String spousesName = (String) bw.getPropertyValue("");

Information obtained via reflection is cached for efficiency, so using a BeanWrapper imposes relatively little overhead. Sometimes values to be set must be provided as strings (for example, the values of HTTP request parameters). The BeanWrapperImpl class can automatically convert a string representation to any primitive type. However, sometimes a string representation must be used to create a custom object. The com.interface21.beans package supports the standard JavaBeans API approach to this problem. We can register a java.beans.PropertyEditor implementation for the class in question, implementing the setAsText() method, and the BeanWrapper class and all classes that use it will automatically gain the ability to create the class from strings. The JavaBeans API provides the java.beans.PropertyEditorSupport convenience class, which we can extend to implement property editors very easily. Consider the following class that can create TestBean objects from strings of the form <name>_<age>:

 class TestBeanEditor extends PropertyEditorSupport {
 public void setAsText(String text) {
 TestBean tb = new TestBean();
 StringTokenizer st = new StringTokenizer(text, "_");
 tb.setAge(Integer.parseInt (st.nextToken()));

We ignore the GUI-oriented methods of the java.beans.PropertyEditor interface, inheriting the default implementations provided by the PropertyEditorSupport class. The setValu() method, highlighted in the above listing, sets the object value that will be returned by the PropertyEditor for the given input string. We can register this PropertyEditor using standard JavaBeans machinery as follows:

 PropertyEditorManager.registerEditor(ITestBean.class, TestBeanEditor.class);

Now we can set properties of type ITestBean as follows:

 TestBean rod = new TestBean();
 BeanWrapper bw = new BeanWrapperImpl(rod);
 bw.setPropertyValue("spouse", "Kerry_34"); 

The BeanWrapperImpl class registers a number of property editors (defined in the com.interface21.beans.propertyeditors package) by default. These include support for java.util.Property objects (specified in any format supported by the java.util.Property class) and string arrays (specifying in CSV format).

Using a "Bean Factory"

The com.interface21.beans package provides powerful functionality, but it's too low-level for direct use in most cases. It's essentially a building block, on which we can base a higher level of abstraction that conceals the low-level details. However easy we make bean-based "late binding", we usually want to use ordinary Java invocation in app code. It's simpler, faster (although the performance overhead of reflection is often exaggerated) and, unless we want to do something unusual, good design will normally mean that we know which interfaces (but not which concrete classes) we are working with. At app startup, however, it's a different matter. The complexity can be managed by framework code; performance overhead is negligible, as initialization operations will account for a tiny proportion of total app activity; and, most importantly, there are very good reasons to use late binding in this situation.


The com.interface21.beans. factory package defines a way of obtaining beans by name from a central configuration repository using a "bean factory". The goal of a bean factory is to remove any need for individual Java objects to read configuration properties or instantiate objects. Instead, configuration is read by a central component, the bean factory, and the bean properties exposed by each app object are set to reflect configuration data. The factory then makes available instances of beans, each with a unique name. Sophisticated object graphs can be created within the bean factory, as managed beans may reference other beans within the same factory.

Our implementation of a bean factory uses the com.interface21.beans package, concealing its low-level concepts from app code. To illustrate the power of this approach, consider the business objects in our sample app. Most of our business objects need access to two fundamental business objects: the Calendar object, which returns information about genres, shows, and performances, and the BoxOffice object, which implements the tutorialing process. A single instance of each of the Calendar and BoxOffice should be shared across the whole app. An obvious approach would be to make the Calendar and BoxOffice singletons, and for business objects requiring them to obtain references using their getInstance() methods. Such an approach is used in many apps, but it has the following disadvantages:

These problems could be slightly relieved by separating object creation (in a traditional factory) from object implementation, but the major objections would remain. The "bean factory" described here differs from a traditional factory in that it is generic. It can create objects of any type, based on configuration information supplied at run time. In my experience, the loss of type safety — an issue only on app initialization, and which is largely concealed within infrastructure code — is far more than made up by the enormous gain in flexibility. Using the bean factory approach described below, Calendar and BoxOffice would be interfaces, not concrete classes. Implementations of each of these interfaces would expose JavaBean properties allowing a bean factory to configure them. Bean properties might be primitives, or might be objects, resolved by references to other beans in the bean factory. The work of configuration would be moved entirely out of app code into infrastructure. Each business object requiring these objects would also be a JavaBean, and would expose calendar and boxOffice properties enabling the bean factory to "wire up" the app on initialization. app classes would contain no irrelevant configuration management code, configuration management would be consistent, and app code would be wholly written to interfaces, rather than concrete classes. This would ensure that the app was totally "pluggable": the implementation of any interface could be switched in configuration without changing a line of Java code.


If the Calendar and BoxOffice objects were EJBs, client code could look them up via JNDI, which would also avoid dependence on a concrete class. However, an EJB container is a very heavyweight "bean factory" if it delivers no other value, and client code would be considerably complicated by EJB access code.

There's widespread awareness of the serious disadvantages of singletons. However, no superior alternative seems to be in widespread use. The core Java java.beans.beancontext package uses a similar approach to that discussed here, although it's complex, GUI-oriented, and appears to be rarely used. The Apache Avalon server framework is also somewhat similar, but more complex, and with a greater requirement on app code to implement framework interfaces (see JMX offers the potential for a widely adopted, standards-based solution, but is far more heavyweight and complex. Perhaps the package that comes closest to the goals we've set is the Digester, formerly part of Struts and now a distinct open source project in Apache Commons. This uses a rule-based approach for configuring Java objects (usually, but not necessarily, JavaBeans) from an XML representation, which also relies on the use of reflection. The Digester is more flexible for XML-based mapping than the XML bean factory implementation described in this chapter, but is tied to XML, and cannot support mapping definitions held in other representations. The Digester is also arguably less intuitive, and typically requires the app developer to write more code (see for more information). The com.interface21.beans.factory.BeanFactory interface contains only two methods:

 public interface BeanFactory {
 Object getBean(String name) throws BeansException;
 Object getBean(String name, Class requiredType) throws BeansException;

The first method enables beans to be obtained by name as follows:

 MyInterface mi = (MyInterface) getBean("myInterface");

The second method is a convenience method that throws an exception if the object found is not of the required type. The following line of code is the same as the above, with this added check:

 MyInterface mi = (MyInterface) getBean("myInterface", MyInterface.class);

Depending on the implementation, the getBean() method may return a singleton (a shared instance returned by all getBean() calls with the same name argument in the current bean factory) or a prototype (an independent instance based on configuration managed by the bean factory). The shared instance approach is the more valuable, and is used most often. By maintaining a single bean factory, an app can avoid the need for individual app classes to be implemented as singletons: the "singleton" functionality is enforced by the bean factory. Should requirements change, we can choose how many bean factories we want to use in our app. Once we've separated configuration management (handled by a framework bean factory implementation) from app code (in app-specific JavaBeans), we can easily hold configuration in any format we choose. The bean definition format used most in the sample app is an XML document as used by the com.interface21.beans.factory.xml.XmlBeanFactory implementation of the BeanFactory interface. Consider the same simple bean class (TestBean) we discussed above. Using the XML format, we can achieve the same object graph without any Java coding, as follows. The XML format is largely self-describing, with name attributes identifying property names and element values containing string representations of property values. Note the references to other beans within the bean factory, which I've highlighted:

 <property >Rod</property>
 <property >31< /property>
 <property beanRef="true">kerry</property> 
 <bean class="com.interface21.beans.TestBean">
 <property >Kerry</property>
 <property > 34</property>
 <property beanRef="true">rod</property> 

With this definition we could obtain a reference to the shared instance of the first bean as follows:

 TestBean rod = (TestBean) beanFactory.getBean("rod"); 

Another implementation of the BeanFactory interface,, can read definitions from properties files. This is a simpler way of defining beans than XML documents, which can tie in with the core Java internationalization support provided by the java.util.ResourceBundle class. The above beans could be defined as follows using the properties syntax, which specifies the class of each bean and again sets property values as strings:


Note the special (ref) suffix used to indicate which properties are references to other beans defined in the same bean factory. Another framework implementation used in the sample app, com.interface21.jndi.JndiBeanFactory, takes bean definitions from EJB environment variables, defined in ejb-jar.xml. This is a more verbose format (the way in which environment variables must be defined), so I'll show only the start of the above definitions using this syntax:


The com.interface21.jndi.JndiBeanFactory implementation enables EJBs to use the same configuration management as other Java classes, and avoids the need to write verbose JNDI lookup code to retrieve environment variables in app EJBs. There is no limit to potential implementations of the BeanFactory interface: for example, they could read data from a database, or deserialize persistent objects or create new objects without using reflection at all. A useful subinterface of BeanFactory,ListableBeanFactory, adds the ability to query all definitions (while a BeanFactory implementation might load bean definitions only on request, a ListableBeanFactory, must know about all possible bean definitions). Our XmlBeanFactory is actually a ListableBeanFactory, as it parses the XML input as a DOM document. The ListableBeanFactory interface is defined as follows:

 public interface ListableBeanFactory extends BeanFactory {
 String[] getBeanDefinitionNames();
 int getBeanDefinitionCount();
 String[] getBeanDefinitionNames(Class type);

The ability to find all bean definitions of a given class or interface can be very useful during initialization: for example, it allows the web app framework described in the next chapter to obtain references to all classes that can handle HTTP requests. Often a bean needs to know when all its properties have been set, so that it can validate its state and/or perform initialization. Our bean factory defines an approach for this. If a bean created by a bean factory implements the com.interface21.beans.factory.InitializingBean interface, it will receive a callback after all properties have been set. The InitializingBean interface includes a single method:

 public interface InitializingBean {
 void afterPropertiesSet() throws Exception;

A typical implementation of this method might check that one or more properties have been set to valid values, before performing initialization. The following example checks that a jndiName property has been set before trying to perform aJNDI lookup:

 public final void afterPropertiesSet() throws Exception {
 if (this .jndiName == null || this.jndiName.equals (""))
 throw new Exception ("Property 'jndiName' must be set on " +
 Object o = lookup(jndiName) ;
 initialize (o);

As all app objects will be created by a bean factory, we can use this in any app class that does not have its own lifecycle management solution. Sometimes we may want to create a bean definition that performs custom processing before returning a bean instance. For example, we might need a bean definition that registers the returned bean as a JMS listener; creates an object of a specified class and returns a dynamic proxy wrapping it; or returns a bean resulting from a method invocation on another object. The bean factory concept supports "custom bean definitions", in which a custom bean definition class can perform any action before returning a bean. A custom bean definition works as follows:

The following custom bean definition illustrates this:

 <customDefintion property="listenerBean">
 <customDefinition property="topicConnectionFactoryName">
 <customDefinition property= "topicName">
 <property beanRef="true">calendar</property>

The definitionClass attribute of the <bean> element indicates that this is a custom bean definition, and supplies the custom definition class. The <customDefinition> elements set properties on the custom definition. The meaning of properties will vary with custom definition class. In this example, the listenerBean property specifies the class of the actual returned bean. In the above list, the custom definition will create an instance of DataUpdateJmsListener and register it as a JMS listener.

The <property> element sets the cachingCalendar property of the actual returned bean. This mechanism makes the bean factory interface indefinitely extensible. It's particularly valuable for concealing the complexity of J2EE API usage.

The app Context

The bean factory concept solves many problems, such those resulting from overuse of the Singleton design pattern. However, we can move to a higher level of abstraction to help to pull apps together.

app Context Goals

Building on the bean factory, an app context provides a namespace for the JavaBeans that compose an app or subsystem, and the ability to share working objects at run time. The com.interface21.context.appContext interface extends the ListableBeanFactory interface, adding the ability to:

The most important added methods in the appContext interface are:

 appContext getParent();
 void publishEvent (appEvent e);
 void shareObject (String key, Object o);

An app context is a directory of cooperating beans that offers some additional services. The sample app uses the appContext implementation, which is associated with a javax.servlet.ServletContext object provided by the web container, and which uses the XML bean definition format we've already seen. However other implementations do not require a web container, and allow testing (or the building of apps) without a web interface. Each bean in the app context is given access to the app context if it requires. It simply needs to implement the optional com.interface21.framework.context.appContextAware callback interface, enabling it to access other beans, publish events, or look up messages. This interface contains only two methods, making it very simple to implement:

 public interface appContextAware {
 void setappContext (appContext ctx)
 throws appContextException;
 appContext getappContext();

However, this capability shouldn't be used without good reason. One of the strengths of the framework described here is that app code can benefit from it without depending on it. This minimizes lockin to the framework and retains the option of configuring the app differently.


Although it is possible for beans to register for notification of the app context they operate within by implementing an optional interface, there are no special requirements for beans used within a bean factory of app context.

Each app context has a parent context. If the parent context is null, it is the root of the app context hierarchy. If the parent context is non-null, the current context will pass to the parent requests for beans it cannot find, and requests for messages it cannot resolve. This enables us to determine precisely how much app state should be shared between different components.

The Observer support provided by an appContext is limited to the current server; it makes no effort to broadcast messages in a cluster (JMS Pub/Sub messaging should be used for this). However, a lightweight event publication framework limited to the current server is still very useful. Often there's no need for messages to be broadcast more widely. Consider, for example, a message that should result in the sending of an e-mail. Using the Observer design pattern, we are able to add listeners that perform such tasks without complicating the code of business objects that generate such events.

Web app Context

An app of type com.interface21.web.context.Webappcontext integrates with the javax.servletContext. In a web app, the app context hierarchy works as follows:

Our sample app uses only one servlet, with the name ticket, and requires no custom global configuration. Hence all bean definitions are placed in the /WEB-INF/ticket-servlet.xml file.

Testing Implications

The infrastructure I've described here is test-friendly: an important consideration.

Although it's possible to integrate an app context with the Servlet API and use a bean factory in an EJB, the core interfaces do not depend on J2EE APIs. Thus it is possible create a test app context enabling tests to be run against app objects without the need for a J2EE server. For example, a JUnit test case could create an XmlappContext from the app context definition documents in a web app, and use it to get beans by name and test their behavior.

Summary of app Configuration Infrastructure

The following UML diagram illustrates the relationship between the framework classes and interfaces we've described:

Java Click To expand

I've omitted some of the implementation classes; the aim is to show the public interfaces. Note that app code doesn't need to work with these classes; it's possible to write an app that is "wired up" by an app context but doesn't depend on any framework classes. The version of the framework used in the sample app doesn't support dynamic reconfiguration. I concluded that the value of such functionality did not justify the complexity it would introduce. However, it could be added if necessary; this approach is much more flexible than using singletons and other "hard-coded" approaches to configuration. Later in this chapter we'll look in more detail at how the sample app's code is simplified by use of this framework.


The infrastructure described above enables us to code to interfaces and never concrete classes, relying on a central configuration manager (an "app context") to "wire up" the app on initialization. This completely removes configuration data and plumbing code from app objects, which merely need to expose JavaBean properties. This also has the advantage that the app code is not dependent on the supporting infrastructure — a problem that affects many frameworks.

Managing API Complexity

Now that we have a strong infrastructure for pulling our app together, let's move on to how infrastructure can be used to tackle the problem of J2EE API complexity. In the following section we'll look at how several of the key J2EE APIs can be made much easier to use and their use less error-prone.

Implementing EJBs

So long as we avoid using infrastructure components that violate the EJB specification (for example, by obtaining the current classloader, which rules out dynamic proxy solutions), there's nothing special about EJB code. However, by deriving app EJB implementation classes from generic superclasses we can greatly simplify EJB code.

Abstract Superclasses for EJBs

We should derive our EJBs from common superclasses that achieve the following goals:

The following UML class diagram shows the hierarchy of EJB superclasses offered by our generic infrastructure, and how they relate to the interfaces required by the EJB specification. All infrastructure classes are in the package. We'll look at a complete code listing for each below.


Note that we don't attempt to provide superclasses for entity beans. Entity beans should use CMP, and shouldn't normally contain business logic, placing the onus on the container to provide infrastructure code.

Java Click To expand

Although there are quite a few classes here, each class is simple and the inheritance hierarchy enables us to support stateless and stateful session beans and message-driven beans without code duplication. The classes above the horizontal line belong to the framework; those below the line show how app EJB implementation classes can extend these framework classes. The root of the inheritance hierarchy — not used directly as a superclass by any app EJBs — is the AbstractEnterpriseBean class. This implements the javax.ejb.EnterpriseBean tag interface and provides standard logging and configuration management. The following is a complete listing:

 import javax.ejb.EJBEXception;
 import javax.ejb.EnterpriseBean;
 import com.interface21.beans.BeansException;
 Import com.interface21.beans.factory.ListableBeanFactory;
 import com.interface21.jndi.JndiBeanFactory;
 public abstract class AbstractEnterpriseBean implements EnterpriseBean {
 protected final Logger logger = Logger.getLogger(getClass().getName();
 private ListableBeanFactory beanFactory;
 protected final ListableBeanFactory getBeanFactory() {
 if (this. beanFactory == null) {
 return this. beanFactory;
 private void loadBeanFactory() {
 logger. info ( "Loading bean factory") ;
 try {
 this.beanFactory =new JndiBeanfactory ("java:comp/env");
 catch (beansFactory ex) {
 throw new EJBException ("Cannot create bean factory", ex);

The protected logger instance variable uses the Java 1.4 logging emulation package discussed in , or standard Java 1.4 logging if available. The getBeanFactory() method lazily loads a bean factory from environment variables. This is very useful, as it avoids the need to use JNDI to look up environment variables, yet allows parameterization at EJB deployment time. We can instantiate and configure helper objects such as DAOs, and put configuration variables in a simple bean. We've replaced a low-level API with the same high-level API we use throughout our apps. By facilitating factoring functionality into helper classes (rather than EJB code) we promote good practice and improve testability. We can often test helper classes used in EJBs without an EJB container. For example, the following environment variables define a DAO for the sample app's BoxOffice EJB:

 <env-entry-type> java.lang.String</env-entry-type>

This particular DAO doesn't require any properties, but these can be set using our bean factory conventions. Simply by editing the ejb-jar.xml deployment descriptor we can change the class of the DAO helper to any other object that implements the interface, without needing to change EJB code. The EJB specification requires all session beans to implement the javax.ejb.SessionBean interface, shown below. This includes the setSessionContext() method and other lifecycle methods:

 package javax.ejb;
 import java.rmi.RemoteException;
 public interface SessionBean extends EnterpriseBean {
 void ejbActivate() throws EJBException, RemoteException;
 void ejbPassivate() throws EJBException, RemoteException;
 void ejbRemove() throws EJBException, RemoteException;
 void setSessionContext (SessionContext ctx)
 throws EJBException, RemoteException;

Thus all session beans can be derived from a simple subclass of our AbstractEnterpriseBean base class that implements the SetSessionContext() to store the SessionContext in an instance variable, and exposes the saved context via a protected getSessionContext() method. We also add an empty implementation of the required ejbRemove() lifecycle method, which can be overridden if necessary:

 package com.interface21.;
 import javax.ejb.SessionBean;
 import javax.ejb.SessionContext;
 public abstract class AbstractSessionBean extends AbstractEnterpriseBean
 implements SessionBean {
 private SessionContext SessionContext;
 protected final SessionContext getSessionContext() {
 return SessionContext;
 public void setSessionContext (SessionContext SessionContext) { ("setSessionContext");
 this.SessionContext = SessionContext;
 public void ejbRemove() { ("AbstractSessionBean NOP ejbRemove");

Stateful session beans can subclass this class directly. Stateful session beans often don't need to implement the ejbRemove() method, but they always need to ensure correct behavior on the ejbPassivate() and ejbActivate() lifecycle methods. We discussed how to implement these methods correctly in . Hence we leave these methods unimplemented in AbstractSessionBean. By contrast, it is illegal for an EJB container to invoke the ejbPassivate() and ejbActivate() lifecycle methods on stateless session beans, although stateless session bean implementation classes are (illogically) required to implement them. Thus stateless session beans can be derived from a simple subclass of AbstractSessionBean, which implements these two lifecycle methods to throw an exception. There is no reason for any subclass to override this implementation, although we can't make these methods final, as it violates the EJB specification. Our superclass for stateless session beans also forces Subclasses to implement a no-argument ejbCreate() method — matching the required create() method on the home interface — by defining this as an abstract method. This moves to compile time a check that would otherwise only take place on EJB deployment, as this method isn't required by the EJB API. Here is the complete listing of the AbstractStatelessSessionBean class, which should be used as a superclass by SLSB implementation classes:

 package com.interface21. ejb. support;
 import javax.ejb.CreateException;
 import javax.ejb.EJBException;
 public abstract class AbstractStatelessSessionBean;
 extends AbstractSessionBean {

 public abstract void ejbCreate() throws CreateException;
 public void ejbActivate()throws EJBException {
 throw new IllegalStateException(
 "ejbActivate must not be invoked on a stateless session bean");
 public void ejbPassivate() throws EJBException {
 throw new IllegalStateException(
 "ejbPassivate must not be invoked on a stateless session bean");

This leaves SLSB subclasses to implement an ejbCreate() method and their business methods. Remember that app EJBs will usually implement a "business methods" interface, ensuring that they match the methods defined on their component interface. In rare situations, an SLSB may override the ejbRemove() method defined in AbstractSessionBean. The implementation of the ejbCreate() method may use the bean factory available from the AbstractEnterpriseBean superclass to create helper objects such as DAOs. These superclasses can by used by EJBs with local or remote interfaces or both. Let's look at an example, showing how the business methods interface pattern can be combined with our generic superclass to ensure that the compiler, not just deployment tools, enforces that an SLSB implementation class is valid. The following business methods interface defines the remote methods of a hypothetical EJB:

 import java.rmi.RemoteException;
 public interface Calculator {
 int getUncacheableValue() throws RemoteException;
 int getCacheableValue() throws RemoteException;

Following the business methods pattern described in the last chapter, the EJB's remote interface will contain no methods of its own, but will extend both this interface and javax.ejb.EJBObject:

 import javax.ejb.EJBObject;
 public interface CalculatorRemote, extends EJBObject, Calculator {

The bean implementation class will implement the business methods interface and extend AbstractStatelessSessionBean. This means that the compiler will force us to implement all the methods required for a valid EJB. I've highlighted the lines in the following listing showing how the ejbCreate() method can be implemented to load a helper object from the bean factory exposed by the AbstractEnterpriseBean base class:

 import java.rmi.RemoteException;
 import javax. ejb.CreatException;
 public class CalculatorEJB extends AbstractStatelessSessionBean
 implements Calculator {

 private MyHelper myHelper;
 public void ejbCreate() {
 this.myHelper = (MyHelper) getBeanFactory().getBean("myHelper");

 public int getUncacheableValue() {
 return 0;
 public int getCacheableValue() {
 return 0 ;

Our superclasses have delivered real value. This EJB implementation class contains no code irrelevant to its business purpose, and is easily able to load helper objects whose configuration is held entirely outside Java code. Let's finish by considering message-driven beans (MDB). MDB implementation classes must also meet some requirements beyond implementing the javax.ejb.MessageDrivenBean interface: they must also implement an ejbCreate() method without arguments; and they must implement the javax.jms.MessageListener interface to handle JMS messages. We can extend AbstractEnterpriseBean to save the MessageDrivenContext and force subclasses to implement an ejbCreate() method as follows:

 package com.;
 import javax.ejb.MessageDrivenBean;
 import javax.ejb.MessageDrivenContext;
 public abstract class AbstractMessageDrivenBean extends AbstractEnterpriseBean
 implements MessageDrivenBean {
 private MessageDrivenContext messageDrivenContext;
 protected final MessageDrivenContext getMessageDrivenContext() {
 return messageDrivenContext;
 public void setMessageDrivenContext(
 MessageDrivenContext messageDrivenContext) {
 logger. fine ("setMessageContext");
 this.messageDrivenContext = messageDrivenContext;
 public abstract void ejbCreate();
 public void ejbRemove() {
 logger. info("ejbRemove");

Although EJB 2.0 supports only JMS messaging, EJB 2.1 supports JAXM messaging as well, meaning that the javax.jms.MessageListener is only one of three alternative messaging interfaces that an EJB 2.1 MDB might implement. Thus, rather than tie the AbstractMessageDrivenBean class to use of JMS, we ensure forward compatibility with EJB 2.1 by putting the requirement to implement javax.jms.MessageListener in a JMS-specific subclass:

 import javax.jms.MessageListener;
 public abstract class AbstractJmsMessageDrivenBean
 extends AbstractMessageDrivenBean implements MessageListener {
 // Empty

An app MDB that subclasses this class is guaranteed to meet the requirements of an EJB 2.0 JMS MDB. A trivial subclass automatically stubbed by an IDE will look like this:

 public class SimpleMDB extends AbstractJmsMessageDrivenBean {
 public void ejbCreate() {
 public void onMessage (Message message) {

As with session beans, the ejbCreate() method can access the bean factory provided by the AbstractEnterpriseBean superclass.

Of course we don't need to use these (or similar) superclasses when implementing EJBs, but as they simplify app code and reduce the likelihood of errors resulting in wasted development-deploy cycles, they provide very good value. There's seldom any problem in the use of concrete inheritance depriving app EJBs of their own inheritance hierarchy. Due to the EJB coding restrictions, making an object an EJB by subclassing it to implement the required lifecycle methods is rarely a good idea. Our solution, however, makes it easy for a new EJB to use existing code, through using existing classes as helper objects instantiated through its bean factory. Custom app EJB superclasses can simply subclass one of the above framework superclasses to add additional app-specific behavior.

Accessing EJBs

It's important to achieve loose coupling between EJBs and code that uses them. There are many disadvantages in EJB client code accessing EJBs directly:

Most importantly, if we allow code to work with EJB access APIs directly, we tie code unnecessarily to a particular implementation strategy.


Abstract inter-tier communication with Java interfaces, not on J2EE technologies such as EJB. Technologies are features of implementations.

Two well-known J2EE patterns — the Service Locator and Business Delegate patterns — address these problems. In this section, we'll discuss their benefits and how to implement them. As with implementing EJBs, generic infrastructure classes can be used to simplify app code. We can integrate EJB access with our overall app infrastructure by making service locators and business delegates JavaBeans, configured by an app bean factory.

Local versus Remote Access

There's a profound difference between accessing EJBs through local and remote interfaces. Invoking an EJB through a local interface isn't radically different from invoking an ordinary Java object. The EJB container will intercept each method call, but both caller and EJB are running in the same JVM, meaning that there is no possibility of distributed failures and no serialization issues. Remote invocation is a completely different problem. We may encounter distributed failures, and we must consider efficiency: "chatty" calling, or exchanging an excessive amount of parameter data, will prove disastrous for performance. We can choose between two fundamental strategies for remote invocation: we can try to achieve local-remote transparency, concealing from callers the issue of remote invocation; or we can use a client-side façade to provide a locally accessible point of contact for the EJB invocation. I don't advocate local-remote transparency. As the designers of Java RMI didn't either, it's relatively hard to achieve when invoking EJBs. Secondly, it's an invitation to gross inefficiency.

It's much better to provide a local façade through which all communication with the EJB tier passes. This is an excellent app for the Business Delegate pattern, which is discussed below.

The Service Locator and Business Delegate J2EE Patterns

The first step in decoupling calling code from an EJB implementation is to ensure that all EJB references are obtained through a common factory. This avoids the duplication of JNDI lookup code, and enables the caching of the results of JNDI lookups to boost performance (although the overhead varies between servers, obtaining a naming context and looking up a home interface are potentially expensive operations). Such an object is called a service locator (Core J2EE Patterns). The disadvantage is that clients will still need to work directly with the EJBs. They must still handle remote exceptions in a distributed app and may need to catch exceptions thrown when creating EJBs. However, a service locator can return references to SLSB EJB instances, rather than merely home interfaces (the service locator can invoke the no argument create() method as necessary). This frees clients of the need to handle the checked exceptions that may be thrown by attempting to create an EJB from a home interface. When this is possible, clients needn't know that EJB is being used to implement business interfaces. This is clearly desirable; unless we use EJB to implement a distributed model, there's no reason to view EJB as more than a helpful framework for particular implementations of business interfaces. The Service Locator pattern works well with local EJB access.

Let's consider two approaches to service location where SLSBs are concerned.

Using a Typed Service Locator to Access EJBs

In the first approach, we use a dedicated, thread-safe service locator for each SLSB. Each service locator implements a factory interface that isn't EJB-specific: a method that can be implemented to return any implementation of the relevant business interface. When an EJB is used to implement this interface, the object returned will be an EJB reference, and the EJB's component interface will extend the business interface. In my preferred implementation of this approach, the factory method throws a runtime exception, not a checked exception, as failure to create a business object is likely to be fatal. If it's possible to retry, the service locator can retry before throwing an exception to callers. Each service locator implementation will need to perform a JNDI lookup to cache the home interface for the relevant EJB. This suggests the use of generic infrastructure classes to conceal the use of JNDI. Our framework includes convenient support for this; app service locators need merely to subclass the com.interface21.ejb.access.AbstractLocalStatelessSessionServiceLocator class and implement the abstract setEjbHome() method as well as the relevant factory interface. The com.interface21.ejb.access.AbstractLocalStatelessSessionServiceLocator class extends the com.interface21.jndi.AbstractJndiLocator class, which can be used to perform any JNDI lookup and cache the result. This allows the Service Locator pattern to be used not only for EJB access, but also to look up and cache any resource obtained through JNDI. The AbstractJndiLocator class is designed for use as a Java bean in our app framework. The following is a complete listing:

 package com.interface21.jndi;
 import javax.naming.NamingException;
 import com.interface21.beans.factory.InitializingBean;
 public abstract class AbstractJndiLocator implements InitializingBean {
 protected final Logger logger = Logger.getLogger(getClass().getName());
 private static String PREFIX = "java:comp/env/";
 private String jndiName;
 public AbstractJndiLocator() {

The JndiName property setter enables the JNDI name of the EJB or other resource to be held outside Java code:

 public final void setJndiName (String jndiName) {
 if (!jndiName.startsWith(PREFIX))
 jndiName = PREFIX + jndiName;
 this.jndiName = jndiName;
 public final String get JndiName() {
 return jndiName;

The implementation of the afterPropertiesSet() method, which is invoked by the bean factory after all properties have been set, performs the JNDI lookup. If the object is successfully located, the afterPropertiesSet() method invokes the abstract template method located() with the object. Subclasses must implement this to perform their own initialization, based on the type of object. If the lookup fails, the resulting javax.Naming.NamingException is thrown to be handled by the app framework (this will be considered a fatal initialization exception):

 public final void afterPropertiesSet() throws Exception {
 if (this.jndiName == null || this.jndiName.equals(""))
 throw new Exception ("Property 'jndiName' must be set on " +
 Object o = lookup(jndiName);
 located (o);
 protected abstract void located (Object o);
 private Object lookup (String jndiName) throws NamingException {"Looking up object with jndiName "' + jndiName + ""');
 // This helper will close JNDI context
 Object o = new JndiServices().lookup(jndiName);
 logger.fine("Looked up objet with jndiName "' + jndiName +
 "' OK: [" + o + "]");
 return o;

The AbstractLocalStatelessSessionServiceLocator subclass implements the located()template method to check that that the object is actually an EJB local home, and to invoke an abstract setEjbHome() method that must be implemented by subclasses that know the app-specific type of the EJB home, enabling them to obtain EJB references from it:

 package com.interface21.ejb.access;
 import javax.ejb.EJBLocalHome;
 import com.interface21.beans.FatalBeanException;
 import com.interface21.jndi.AbstractJndiLocator;
 public abstract class AbstractLocalStatelessSessionServiceLocator
 extends AbstractJndiLocator {
 public AbstractLocalStatelessSessionServiceLocator() {
 public AbstractLocalStatelessSessionServiceLocator (String jndiName) {
 protected abstract void setEjbHome (EJBLocalHome home);
 protected final void located(Object o) {
 if (! (o instanceof EJBLocalHome))
 throw new FatalBeanException("Located object with JNDI name "' +
 getJndiName() + "' must be an EJBLocalHome object", null);
 setEjbHome((EJBLocalHome) o);

It's always safe to cache a reference to a local EJB home interface. Although the EJB specification (§6.2.1) implies that it's safe to cache a remote home, there is a slight chance that a cached remote home reference may become "stale" in some servers (for example, if the remote server hosting the EJB was restarted during the client's lifetime). The following UML class diagram illustrates the superclasses for both local and remote SLSB service locators, and how a LocalSLSBBoxOfficeFactory class might be used in the sample app to create BoxOffice objects (actually EJBs) as required:

Java Click To expand

Let's look at how these superclasses can be used to simplify the implementation of a real service locator. The BoxOfficeFactory interface is the public interface of our app-specific typed service locator:

 public interface BoxOfficeFactory {
 BoxOffice getBoxOffice() throws FatalException;

Extending the com.interface21.ejb.access.AbstractionLocalStatelessSessionServiceLocator superclass makes it trivial to implement this interface:

 public class LocalSLSBBoxOfficeFactory
 extends AbstractLocalStatelessSessionServiceLocator
 implements BoxOfficeFactory {

The implementation of the protected abstraction setEjbHome() method caches the home interface, after casting it to the appropriate type. This method will be invoked once, when the service locator is initialized:

 private BoxOfficeHomehome;
 protected void setEjbHome(EJBLocalHome home) {
 this.home = (BoxOfficeHome) home;

The implementation of the getBoxOffice() method from the BoxOfficeFactory interface, which will be invoked by code using the EJB, creates a new SLSB reference as required. EJBCreate exceptions are caught and an unchecked exception, FatalException, is rethrown:

 public BoxOffice getBoxOffice() throws FatalException {
 try {
 return home.create();
 catch (CreateException ex) {
 throw new EjbConnectionFailure(
 "Cannot create BoxOffice EJB from home"), ex);

The following bean definition shows how such a service locator could be defined in the sample app's bean factory. The only property that must be set is jndiName, inherited from the AbstractJndiLocator superclass:

 class="com.wrox.expertj2ee.ticket.framework.ejb.LocalSLSBBoxOfficeFactory" >
 <property >ejb/BoxOffice</property>

This is a simple approach that works very well with local EJBs. It hides EJB access from code that uses the business interface. One disadvantage is that it requires a factory interface and an implementing class for each EJB. This isn't usually a major problem, as with sensible design few systems need a vast number of EJBs. Slightly more seriously, all code that uses the EJB must work with the factory object: it's impossible to hold on to a reference to the business interface.

Transparent Dynamic Proxy: An Alternative to the Typed Service Locator for Local EJB Access

An alternative to the Service Locator pattern that achieves the same end is to conceal the factory in a custom bean definition, as described when we discussed our "bean factory" approach above. The custom bean definition looks up and caches the bean's home interface before returning an object of the required interface, which is actually a dynamic proxy wrapping a new instance of the SLSB. Before each method invocation, the dynamic proxy — which is threadsafe — transparently creates a new instance of the SLSB. Although the custom bean definition doesn't know the type of the EJB, it knows that an SLSB local interface must expose a create() method without arguments, which it can use a BeanWrapper object to invoke by name. Benchmarks show that this approach has only a small performance overhead. This use of dynamic proxies and reflective method invocation sounds complex, but the complexity is hidden within framework code; it enables us to write less app code. apps need only define a bean using the custom bean definition, as follows. Note the specification of the JNDI name and business interface:

 <customDefinition property="businessInterface">
 <customDefinition property="jndiName">

That's it: calling code can simply obtain a BoxOffice object like this, and cache it:

 BoxOffice boxOffice=(BoxOffice) beanFactory.getBean("boxOffice");

Most likely, this won't even be necessary: objects that need to use the BoxOffice interface can simply expose a bean property and have the app context set it to the boxOffice reference at run time. This approach has the advantage of requiring no custom code to access an EJB. We need only define a bean using the custom definition. This is the approach used in the sample app, although it would be simple to switch to the Typed Service Locator approach, code for which is included in the download.


See the code in the com.interface21.ejb.access.LocalStatelessSessionProxyBeanDefinition class for the implementation of this approach.

Using the Business Delegate Pattern for Remote EJB Access

A higher level of decoupling is achieved by the Business Delegate pattern, in which a client-side object exposes business methods that are implemented by calls to the EJB. This is more of a façade than a proxy approach, as the business delegate may change method signatures — for example, changing exception types or combining method calls, or even invoking multiple EJBs. As the Business Delegate pattern requires more work to implement than the Service Locator, I'll focus on its use with remote interfaces, with which it delivers real value (its benefits are reduced with local EJB access). The benefits of a business delegate approach include:

The drawback of using a business delegate is the potential duplication of the business interface exposed by the EJB tier on the client-side. However, using a business delegate offers an opportunity to provide an interface that best fits the needs of clients. For example, we can simplify the interface exposed by the EJB tier by omitting irrelevant operations. We can simplify client code by only throwing checked exceptions if they're part of the API, and the client can be expected to handle them. It's superficially attractive for the business delegate to implement the session bean's business methods interface. However, this fails to decouple EJB tier and client tier, and cannot deliver some of the benefits we've identified, such as concealing remote exceptions and simplifying the client API. Hence, I don't recommend copying method signatures in the business delegate (the approach recommended in EJB Design Patterns). If this is appropriate, the Service Locator pattern is simpler and should be preferred. Our framework provides easy support for implementing business delegates. The same superclass we used for the typed service locator, AbstractLocalStatelessSessionServiceLocator, can be used as a superclass for a business delegate. Instead of merely returning an instance of the EJB on demand, a subclass would implement business operations, calling the EJB as necessary. As the sample app uses EJBs with local interfaces, there is no need to use the Business Delegate pattern, which requires more work to implement than a service locator. The following example illustrates the use of a business delegate to access a remote EJB. It uses a hypothetical EJB with a remote interface that exposes two int values: one of which can be cached, and one of which cannot. We saw this EJB's business methods interface and component interface under Implementing EJBs above. The remote interface exposes the following business methods:

 int getUncacheableValue() throws RemoteException;
 int getCacheableValue() throws RemoteException;

By using the Business Delegate pattern, we can simplify calling code by hiding remote exceptions and rethrowing unchecked fatal exceptions, and improve performance by caching the cacheable data value for a given period. When using the Business Delegate pattern, it is good practice to define a business delegate interface, which app code will work with. This enables a caching implementation to be substituted without impact on client code, for example. The interface might look as follows for this EJB:

 public interface MyBusinessDelegate
 int getUncacheableValue() throws FatalException;
 int getCacheableValue() throws FatalException;

The following implementation extends the AbstractRemoteStatelessSessionServiceLocator framework superclass, which performs the necessaryJNDI lookup and provides it with an EJB home it can cache in the setEjbHome() method:

 public class MyBusinessDelegateImpl
 extends AbstractRemoteStatelessSessionServiceLocator
 implements MyBusinessDelegate {
 private static long MAX_DATA_AGE = 10000L;
 private CalculatorHome home;
 private long lastUpdate = OL;
 protected void setEjbHome(EJBHome home) {
 this. home = (MyHome) home;
 private CalculatorRemote create() throws FatalException {
 try {
 return home . create();
 catch (CreateException ex) {
 throw new EjbConnectionFailure{
 "Cannot create BoxOffice EJB from home", ex);
 catch (CreateException ex) {
 throw new EjbConnectionFailure (
 "Cannot create BoxOffice EJB from home", ex);
 public int getUncacheableValue() throws FatalException {
 try {
 return create() .getUncacheableValue();
 catch (RemoteException ex) {
 throw new EjbConnectionException("Can't connect to EJB", ex);
 public synchronized int getCacheableValue() throws FatalException {
 if (System.currentTimeMillis() - lastUpdate > MAX_DATA_AGE ) {
 try {
 this. cachedValue = create() .getCacheableValue();
 lastUpdate = System. currentTimeMillis();
 catch (RemoteException ex) {
 throw new EjbConnectionException ("Can't connect to EJB", ex);
 return this.cachedValue;


It's important to abstract access to EJBs. With EJBs with local interfaces, use the Service Locator pattern, or the Business Delegate if there is a good reason that calling code shouldn't work with the EJB interface. With EJBs with remote interfaces, use the Business Delegate pattern, and conceal remote access details from clients.

Using JMS

LikeJDBC,JMS is a complex API. Working with it directly can obscure the purpose of app code. Thus an abstraction layer is appropriate. The com.interface21.jms.JmsTemplate class applies the same approach as the JdbcTemplate we examined in . We should try to conceal in framework code the complexity of the necessary JNDI lookups and the requirement to work with multiple JMS API objects. Let's consider com.interface21.jms.JmsTemplate class's support for Pub/Sub messaging. On startup, a JmsTemplate instance does aJNDI lookup for the TopicConnectionFactory. TheJNDI name is passed into the constructor, as it may differ between app servers. The following method uses the cached TopicConnectionFactory to invoke a callback interface to create a message given a TopicSession, which it then publishes:

 private static String PREFIX = "java:comp/env/";
 public void publish (String topicName, pubsubMessageCreator
 pubSubMessageCreator) throws JmsException {
 if (! topicName.startsWith(PREFIX))
 topicName = PREFIX + topicName;
 TopicConnection topicConnection = null;
 try {
 topicConnection = topicConnectionFactory.createTopicConnection();
 TopicSession session = topicConnection.createTopicSession(
 false, Session. AUTO_ACKNOWLEDGE);
 Topic topic = (Topic) jndiServices. lookup ( topicName);
 Topicuploader uploader = session. createuploader (topic);
 Message message = pubSubMessageCreator. createMessage (session);
 logger. info ("Message created was [" + message + "]");
 uploader. publish (message);
 logger. info ("Message published OK");
 catch (NamingException ex) {
 throw new JmsException ("Couldn't get topic name [" + topicName + "]", ex);
 catch (JMSException ex) {
 throw new JmsException ("Couldn't get connection factory or topic", ex);
 finally {
 if (topicConnection != null) {
 try {
 topicConnection. close();
 catch (JMSException ex) {
 logger.logp (Level.WARNING, "com.interface21.jms.JmsTemplate",
 "publish", "Failed to close topic", ex);

The com.interface21.jms.JmsException exception is unchecked, meaning that we have a choice as to whether to catch it. Calling code can implement the PubSubMessageCreator inner interface of JmsTemplate (shown below) without deep knowledge of JNDI:

 public interface PubSubMessageCreator {
 Message createMessage (TopicSession topicSession) throws JMSException;

Thus a message can be published with the following code:

 JmsTemplate jmsTemplate = new JmsTemplate("jms/TopicFactory") ;
 jmsTemplate. publish ("jms/topic/referencedata",
 new JmsTemplate. pubSubMessageCreator() {
 public Message createMessage(TopicSession session) throws JMSException {
 TextMessage msg = session.createTextMessage();
 msg.setText ( "This is a test message");
 return msg;

Message consumers can also benefit from a simplifying infrastructure. Note that it's often best to use MDBs as message consumers, as the EJB container provides valuable infrastructure for JMS message consumption; however, we can't always use EJB. We always need to implement the MessageListener interface. However, we don't want to have to deal with the complexity of registering a listener with a topic, which also involves multiple JNDI lookups. The JmsTemplate class provides a convenience method for this, with the following signature:

 public TopicConnection subscribeToTopicNonDurable ( String topicName,
 MessageListener listener, String messageSelector)
 throws JmsException;

A custom bean definition of class com.interface21.jms.JmsListenerBeanDefinition can automatically register any JMS listener to a given topic. The following example is from the sample app, in which the JMS listener notifies caching objects of a data update:

 <customDefinition property= "listenerBean">
 <customDefinition property="topicConnectionFactoryName">
 <customDefinition property="topicName">
 <property beanRef="true">

This enables us to implement a simple JMS listener that responds to events and refreshes data cached in another app component without the need to write any low-level JMS code, as shown in the following listing:

 public class DataUpdateJmsListener implements MessageListener {
 protected final Logger logger = Logger.getLogger(getClass().getName() );
 private CachingCalendar calendar;

 public void setCachingCalendar (CachingCalendar calendar) {
 this.calendar = calendar;

 public void onMessage (Message m) {
 try { ("Refresing calendar in response to JMS message [" + m
 + "]" );
 catch (Exception ex) {
 logger.logp (Level.SEVERE, getClass().getName(), "onMessage",
 "Failed to refresh calendar", ex);

This simple abstraction doesn't take care of all JMS requirements — the JMS API includes many features such as transacted sessions, which pose more problems for abstraction. However, it provides a simple infrastructure for the commonest needs.