Approaches to J2EE Architecture

Building applications with multitier architectures involves the use of distributed computing, a complex area of software engineering. Although the J2EE platform does much to simplify the development of three-tier systems, distributed computing makes designs of this nature inherently more complex than systems comprised of only one or two tiers. This added complexity means architects should carefully consider whether the requirements of the system justify a distributed solution.

In the past, the prominence of Enterprise JavaBeans (EJBs), the flagship technology of the J2EE platform, has lead some architects to produce complex multitier architectures for systems whose requirements would have been met with a simpler model.

Although EJB technology has possibly the highest profile of all the J2EE services, Enterprise JavaBeans form only part of the J2EE specification, and their use is not mandatory in all J2EE applications. Furthermore, EJB architectures are possible that do not rely on the remote-method invocation services of the J2EE container.

If you can avoid the use of a distributed architecture for systems that do not require it, then simpler designs result. Avoiding complexity in this way is important for rapid development projects, as complex designs can wreak havoc on tight schedules.

Complexity makes:

  • Designs and code difficult to understand

  • Timeframes longer due to steep learning curves

  • Software maintenance expensive

  • Changes difficult to assess and apply

  • Mistakes easy to make

Over the course of the next sections, we examine the strengths and weaknesses of distributed systems and consider possible architectures that do not rely upon the services of distributed components.

Two-Tier Versus Multitier Architectures

Prior to the emergence of distributed computing technologies like J2EE and CORBA, enterprise information systems typically adopted a two-tier, or client/server architecture. Under the client/server model, business logic was implemented as an integral part of a rich, or fat, client application that accessed data housed in a central database server.

The client/server model enjoyed considerable success. It was easy to understand, simple to test, and well supported by numerous high-level visual development tools. These benefits made the client/server architecture ideal for rapid development. Sadly, two-tier architectures do have some key shortcomings:


The client/server model sees all functionality built as a monolithic, standalone application and deployed directly to the client machine. Large organizations requiring widespread deployments to thousands of desktops face a huge, logistical challenge. Often, deployments of this nature can only be made out of hours, or in some extreme cases, over the course of a weekend. Consequently, while the two-tier model enables software changes to be applied quickly, it has inherent weaknesses when it comes to releasing new, business-critical, functionality in a timely manner.

Sharing of services.

The monolithic structure of client/server applications presents some very difficult problems when it comes to sharing services between applications across the enterprise. Increasingly, organizations require their core IT systems to share information or services. The lack of a centralized business or services tier in the client/server model makes this all but impossible. One option is to share common code modules, or components, between systems. However, this again presents deployment problems.

Poor separation of presentation and business logic.

Placing business and presentation logic within the same tier can lead to a commingling of these two concerns. Arguably, this is an indication of poor design rather than a true weakness of a client/server architecture. A well-designed application would see the two layers cleanly decoupled using well-founded object-oriented design practices. Unfortunately, often over the course of the lifetime of the system, software entropy sees the two layers merge without the benefit of physically separate tiers to keep the layers logically distinct.

In searching for a solution to the shortcomings in the client/server model, developers concluded that you can never have too much of a good thing. If splitting systems into two physical tiers proved effective, then the addition of a further tier would also be a good thing. Experience proved them mostly right, and so the middle tier was born.

The use of a middle business tier offers many benefits beyond that of the client server model:

Centralized business intelligence.

The middle tier enables business components to be located in a central location and accessed remotely by disparate systems. Here, the middle tier addresses the problem of core business functionality being effectively locked away within the heavyweight clients of the client/server model.

Ease of deployment.

Thanks to the middle tier, gone is the headache of deploying business components to thousands of desktop machines over the corporate network. With all business components centrally located, changes can be deployed quickly and easily with minimal impact on the system's user base.


The deployment of business components into a clustered middle tier provides built-in redundancy for systems. Thus, the use of multiple machines to replicate the middle tier sees important business components maintained in a high-availability environment.


Clustering components of the middle tier over multiple server nodes also allows for scalability. As system usage increases, so too can the number of machines in the architecture.

These benefits have pushed the multitier model to the forefront as the architecture of choice for enterprise software. The technology of the J2EE platform provides a distributed component model for developing systems with multitier architectures, with Enterprise JavaBeans a key technology for developing business components for deployment to the middle tier.

Enterprise JavaBeans

Enterprise JavaBeans helps realize the RAD concept of developing software using component-based architectures. The EJB architecture defines components that encapsulate functionality into deployable modules with clearly defined interfaces known as enterprise beans.

The J2EE platform supports three types of enterprise bean objects:

  • Session beans, for encapsulating business logic

  • Entity beans, as a mechanism for presenting an object-based view of entities within a persistent data store

  • Message-driven beans, for consuming messages delivered to the server via the JMS API

The remainder of this discussion focuses on the use of session beans for building distributed enterprise solutions.

An EJB architecture provides substantial benefits when building an enterprise system:

  • Improves productivity by managing transaction and security concerns on behalf of the developer based on information specified in the enterprise bean's deployment descriptor

  • Provides scalability by intelligently managing the allocation of resources and transparent state management of stateful components

  • Supports and mediates access to business components by multiple client types, including fat clients and thin browser-based Web applications

  • Insulates the client from networking issues by providing location transparency, whereby methods on a component can be invoked regardless of the physical location of the client or the component

The final point concerning location transparency is of specific interest, as this EJB technology makes possible the development of distributed architectures with the J2EE component model.

Remote and Local Client Views

Clients of session bean objects can view methods on a bean's interface either remotely or locally. With a remote method invocation, a client running in a separately executing Java Virtual Machine (JVM) accesses the bean instance. With local access, the client resides within the same JVM as the bean object. Alternatively, as of the EJB 2.1 specification, clients may access session bean objects through a bean's Web Service. This is essentially another form of remote access.

Clients obtain remote access to a session bean object through the enterprise bean's remote interface and remote home interface. These interfaces ultimately extend the java.rmi.Remote interface, part of standard Java Remote Method Invocation (RMI). By building on RMI, clients can access bean functionality across machines and process boundaries. The complexities surrounding network connection issues are all handled by RMI on behalf of the developer.

An enterprise bean may also expose a local interface. Local interfaces do not offer location transparency, meaning that clients can access a bean only if it is executing in the same JVM through its local interface.

We look at the benefits of local interfaces shortly, but first let's consider some of the implications surrounding the development of enterprise beans that expose remote interfaces to their clients.

Distributed Components

Providing enterprise beans with remote interfaces makes possible the development of systems with distributed architectures. The J2EE platform does a very creditable job of reducing the difficulties associated with building complex architectures of this type. Nevertheless, adding remote interfaces to business components results in certain issues of which the architect must be aware before deciding upon a distributed solution.

Rod Johnson eloquently raised awareness of these issues within the Java community in his book Expert One-on-One J2EE Design and Programming [Johnson, 2002]. These issues include performance overheads, complexity, and object-oriented impedance.


EJB technology relies on standard Java RMI for its distributed capabilities, which provides the client of the enterprise bean with location transparency when accessing the bean through its remote interface. However, the process involved in making a method invocation across a JVM or machine boundary, makes RMI calls several orders of magnitude more expensive than the equivalent calls on a local object.

To understand why remote calls incur a performance penalty, let's review the steps involved in an RMI method call.

In making the call, RMI creates a stub object on the client responsible for sending method parameters and receiving return values across the network. This packaging of method calls for transmission across the wire is called marshaling and is a common approach to remote method calls. RMI uses Java object serialization to convert parameters into a stream of bytes for sending across a network.

The client stub does not talk directly to the object on the server but to an RMI skeleton object, which is the server-side equivalent of the client stub, and retrieves all calls sent across the network before forwarding them to the real object. This server-side skeleton object makes the call on the remote object on the client's behalf.

This same process is followed every time a method on a session bean object's remote interface is called. The overheads of remote method calls means careful design is necessary to ensure the benefits of location transparency do not come at the cost of system performance.


Passing large objects as parameters in remote method calls further reduces performance. If an object contains references to other objects, then these member objects are also serialized as part of the call. To reduce the size of some objects, you can exclude unnecessary objects by marking them with the TRansient keyword.

Since RMI uses Java serialization for marshaling, for very large objects you should consider overriding writeObject() on java.lang.Serializable and implementing some form of compression algorithm. Don't forget to implement a corresponding decompression algorithm for readObject().


Although RMI can make the calling of remote enterprise beans a seamless process, distributed computing still introduces additional complexities for the developer.

The first issue is the need for developers using RMI technology to be aware of the subtle but important differences between making remote calls and calling a local Java object.

Parameters in a remote call are passed by value, due to the need for RMI to copy the parameter in order to send it across the network. If the remote object modifies the state of an object passed to it by value, then the object referenced by the caller does not reflect these changes.

With a call on a local object, parameters are passed by reference. Consequently, if the called method modifies the state of an object passed as a parameter, then the object referenced by the caller does reflect these changes. This is a subtle difference in the semantics of the call, but it can cause frustration for developers unaware that Java's calling conventions have suddenly changed.

Remote clients must also guard against the prospect that networking issues could cause a remote call to fail. Trapping these network errors isn't an onerous task, as you only need to catch thrown java.rmi.RemoteException exceptions. However, complexities arise with the need to handle these exceptions, because they are orthogonal to the standard exceptions a business method would normally throw. The architect must have a strategy in place for satisfactorily handling these remote exceptions and translating them into meaningful error messages for the presentation layer. Avoiding the need to deal with remote exceptions therefore has positive implications for rapid development.

Object-Oriented Impedance

Employing the distributed capabilities of EJB technology requires a change in the way we apply object-oriented design practices.

In a nondistributed architecture, developers work directly with objects from the domain model. Here, domain objects represent business entities and expose interfaces with fine-grained methods, such as get and set methods.

The performance overheads of a distributed application preclude the use of objects with fine-grained methods, as they increase the number of network roundtrips when a client interacts with a remote object.

To keep the number of roundtrips to a minimum, remote interfaces have to be coarse-grained, whereby methods combine the functionality of several fine-grained methods into a single call.

To provide guidance when building distributed architectures, Sun Microsystems published a collection of J2EE design patterns [Deepak, 2003]. These patterns are essential reading for anyone building distributed applications. The Session Façade and Transfer Object patterns both offer effective strategies for managing the performance overheads of remote calls.

Despite the existence of these patterns, they still impose on the architect's object-oriented thinking process. The architect must be aware of the constraints of the implementing technology and reflect this in all designs. Having the implementing technology dictate the makeup of a component's interface is counter to the practice of good object-oriented design.

Choosing the Appropriate Design

Distributed components are not a prerequisite for all enterprise architectures. Unless the requirements of the system dictate a distributed architecture, a simpler application is possible by avoiding the need to employ the remote method invocation capabilities of the J2EE platform. The architectural decision as to whether to use distributed components therefore has a significant impact on rapid development projects.

In this section, we look at two possible J2EE architectures, Web-centric and EJB-centric, although numerous permutations of the two designs presented are possible. The next two sections evaluate the merits of each design from the standpoint of a system whose main architectural driver is the delivery timeframe.

Web-Centric Architecture

One trend in enterprise systems that has become very apparent is the move away from fat user interfaces to lightweight clients. In fact, thanks to the popularity of the browser, user interfaces have become positively anorexic.

The Web application is emerging as the de facto standard for enterprise applications, a trend that has the potential to make the task of developing enterprise software far simpler.

Let's consider a basic J2EE architecture to support an enterprise Web application that does not make use of the services of EJB technology. Figure 4-1 illustrates a Web-centric design.

Figure 4-1. Web-centric enterprise architecture.

Does anything in Figure 4-1 look familiar? The presentation tier is gone. In its place is the Web container (or Web tier), acting as a consolidated presentation and business tier. The browser-based interface enables us to return to a model similar in structure to the classic client/server architecture. Thus, the Web-centric model sees a single JVM housing presentation and business logic in a common Web tier. This design swaps a multitude of client machines for a single server and removes the deployment problems associated with the client/server model.

The Web-centric design shown has just two tiers (or two-and-a-half with the browser): the Web tier, and the EIS tier. The use of layers within the Web tier separates user interface code from business logic.


For clarity, the architecture depicted in Figure 4-1 does not show all of the layers required in an enterprise system. For example, a production system would put in place layers to split business objects from lower-level data access objects.

Business objects are implemented as Plain Old Java Objects, or POJOs, in preference to heavier weight enterprise beans. The term POJO refers to a vanilla Java class that exposes no specialized interfaces.

The nondistributed Web-centric architecture shown in Figure 4-1 has several key benefits:

  • User-interface and business components both execute within the same JVM, providing high performance

  • Using plain Java objects instead of enterprise beans for encapsulating business logic removes the additional configuration and deployment complexities associated with EJB technology

  • Unit testing of the business objects is simpler because, unlike session bean objects, they can be tested without being deployed to the J2EE server

  • No RMI calls are involved, so standard Java pass-by-reference calling conventions remain unchanged

  • Business objects can expose fine-grained interfaces

A prerequisite for most enterprise architectures is scalability. The Web-centric design scales across application servers, although suitable load-balancing hardware or software is required to manage the allocation of requests between server nodes.

Like any solution, the Web-centric architecture has its limitations, including the following:

Supporting Web-interfaces only.

The Web-centric architecture supports only browser-based interfaces. If the system requirements mandate fat clients accessing the business layer remotely, then an EJB architecture is more appropriate. Alternatively, the use of a framework such as Apache's Axis enables business object interfaces to be exposed to heterogeneous remote clients as Web Services.


While it is possible to secure Web applications, plain Java business objects do not offer the same declarative security model as is available for enterprise beans. Securing business objects within the Web-centric architecture to the same method level allowed by EJB technology requires the time-consuming task of writing application-specific security code.

Transaction support.

To support transactions, business objects must implement their own transaction management. The transaction management services of the J2EE server can be invoked programmatically, but this approach involves considerably more effort than the declarative transaction model EJB technology provides.

Threading issues.

The EJB container manages concurrent threads of execution on behalf of the developer. In the Web-centric model shown, the developer is responsible for addressing threading issues. The development of multithreaded systems is notoriously error prone and time consuming.

The next section introduces enterprise beans that expose local interfaces into the Web-centric architecture.

EJB-Centric Architecture

To counter some of the shortcomings in the Web-centric architecture presented previously, this next solution modifies the architecture to incorporate enterprise beans that provide a local view of their interfaces to clients.

Figure 4-2 illustrates a possible EJB-centric architecture for our Web application.

Figure 4-2. EJB-centric enterprise architecture.

The architecture shown Figure 4-2 turns the business objects into session beans and deploys them into the J2EE server's EJB container. The session bean objects that represent the system's business components do not expose remote interfaces. Instead, they each make available a local interface to clients.

The EJB 2.0 specification introduced local interfaces for enterprise beans in response to industry concerns surrounding performance issues with EJB architectures. Placing a local interface on an enterprise bean enables a client resident within the same JVM to invoke the methods on the bean instance using standard Java pass-by-reference calling conventions, avoiding the overheads incurred in a remote call.

In the architecture shown in Figure 4-2, both the J2EE server's Web container and EJB container exist within the same JVM, making the components of the Web application local client's of the session bean objects. The EJB-centric architecture still has the same two-and-a-half tiers as the Web-centric version, with the Web container and EJB container acting as layers within the middle tier.

The benefits of an enterprise architecture built using enterprise beans with local interfaces include the following:

  • Performance is excellent as in-process method invocation does not carry the overheads of Java RMI

  • The declarative model of EJB technology is available for addressing security, transaction management, and thread safety

  • Remote exceptions are not thrown and so do not have to be handled

  • Enterprise beans can expose fine-grained business interfaces

Architecture Prototyping

Using local interfaces is congruent with evolutionary prototyping. Preliminary prototypes can adopt a Web-centric design. As development progresses, the business objects can be evolved into session bean objects exposing local interfaces.

This change is gradual and incremental because the use of local interfaces preserves the original fine-grained interfaces on the business objects. Alternatively, adding remote interfaces to enterprise beans represents a radical departure from the initial prototype, since both the interfaces and the calling code would require a substantial refactoring effort.

The EJB-centric architecture presented represents a valid use of EJB technology where the system requirements call for declarative security and transaction management. Some of the weaknesses of this architecture include:

Supports only Web interfaces.

Despite the introduction of EJB technology, the architecture supports only Web clients colocated within the same JVM.

Physical separation of layers.

It is not possible to split Web components and business components into separate tiers for deployment to different servers.

Configuration overheads.

The EJB architecture introduces configuration overheads for the business components. You should ensure these overheads warrant the benefits EJB technology brings to the architecture.

Container-bound testing.

As enterprise beans, the business components now require the services of the EJB container for unit testing purposes.

The architecture examples discussed are just two possible approaches to building enterprise systems. Simple architectures are faster and easier to implement than complex ones. Distributed architectures introduce complexity. Ensure the requirements of the system justify this additional level of complexity before embracing a distributed component model.

    Rapid J2EE Development. An Adaptive Foundation for Enterprise Applications
    Rapid J2EEв„ў Development: An Adaptive Foundation for Enterprise Applications
    ISBN: 0131472208
    EAN: 2147483647
    Year: 2005
    Pages: 159
    Authors: Alan Monnox © 2008-2017.
    If you may any questions please contact us: