The Java industry has grown exponentially over the last few years. As an enterprise application developer, architect, or technical manager, you can choose from dozens of vendors, best practices, specifications, and component types for your Java technology implementation. The goal of the J2EE pathfinder series is to help you forge a path through these options, by aiding you in the process of selecting the appropriate technology for any given situation.
In this first installment, we'll explore stateless J2EE components and evaluate the most appropriate one to use for your enterprise architecture. When it comes to stateless, request-processing components, you have two primary J2EE technologies to choose from: servlets or Enterprise JavaBeans technology -- or more specifically, stateless session beans.
Broadly speaking, both servlets and EJB components are designed to function as the transaction-management component for an enterprise architecture. Each technology is powerful in its own right. The strength of the servlet architecture is in its overall efficiency and relative simplicity. EJB components, on the other hand, are more robust, and consequently more complicated to develop, maintain, and debug.
We'll begin by briefly discussing the qualities of the stateless (as opposed to stateful) network, then talk in detail about the pros and cons of each of our two stateless technologies. We'll close the article with a broad look at the most common application setups you will encounter in J2EE enterprise programming, and the best technology solutions for each setup given our two options.
Please note that JSP (Java ServerPages) technology is, for the purposes of this article, considered to be a specialized type of servlet. Considering that every JSP page is converted into a servlet prior to execution, this is not a stretch. Because servlets are inherently stateless, we will limit our focus to stateless session beans and the features they provide for handling stateless client requests. The next article in this series will compare stateful session beans with servlets and the HTTP Session API.
The stateless network
Web application protocols break down into two broad categories: stateless and stateful. A protocol's state refers to its ability to "remember" information from one transmission to the next. A stateful protocol is one that creates a context based on the client's previous requests. A stateless protocol has no context; each request is an independent connection to the server.
HTTP is a good example of a stateless protocol based on client-server requests and responses. Under HTTP no memory of the client-server interaction is maintained from one request to another.
Of course, without the ability to maintain state, the Internet would be reduced to a glorified encyclopedia, electronic yellow pages, and cool animated games on Shockwave.com. Thus, there are several tricks for simulating a stateful session over HTTP. Stateful information can be stored in HTML form fields, appended to a hyperlink, or stored in a cookie on the user's machine. It is then the responsibility of the application developer to manage, track, and maintain the client's state to ensure a smooth, secure, and engaging experience.
The case for servlets
The servlet architecture is designed to be a flexible, platform-neutral component model that executes on a server and handles client requests. Servlets are flexible in that they are uniquely configured by a combination of the server's deployment descriptor, which is server specific, and the Web application deployment descriptor (for example, web.xml), which is server-neutral and defined by the J2EE specification. Servlets are platform-neutral in that they will run on any OS (thanks to the JVM) and they operate in any J2EE Web server (thanks to the J2EE standard). Finally, the servlet architecture is a component model because it allows developers to write discreet components that implement certain interfaces. These components are then assembled at run time to process client requests.
Although servlets typically handle HTTP requests, the servlet architecture is protocol independent. The servlet interface defines the basic methods needed for communicating with a servlet, regardless of the network protocol. We will deal exclusively with HTTP servlets, both for simplicity's sake and because they are the most common type. In fact, if you extend your custom servlet classes from
HTTPServlet, you will be able to easily work with and handle HTTP communication without having to worry about the details involved in parsing an HTTP request stream, extracting parameters, or any of the other typical HTTP processing activities.
The servlet architecture
The Model-View-Controller (MVC) design pattern is commonly applied to scenarios that require some kind of human interface. The pattern originated in the Smalltalk community, where it was used for building flexible and reusable user interfaces. Servlets fit naturally into the MVC design methodology. In such an architecture, the model refers to the structure and type of the data being accessed. A model component will typically house business logic that controls access to the data and serves one or more views. The view provides the user interface through which a user or application component accesses the model. Many views can be used to provide different interfaces to the model. Finally, the controller component coordinates the entire communication. The controller handles the processing of client input, the manipulation of the model, and the decision of which view to send to a given client.
From an architectural standpoint, servlets can function both as controllers and views. Typically, JSP pages are used as view components, and JSP pages or pure servlets are used as controller components. Servlets do an effective job of handling user interactions such as content formatting and display, basic request processing, security requests, and more. Typically, a servlet will use helper classes (often JavaBeans-style classes) to handle the heavy processing or use them to interface with back-end components. This allows the servlet layer to focus on client interaction rather than business processing.
Servlets are very lightweight, in that limited resources are required to initialize and maintain a servlet instance. Servlet scalability is particularly smooth and efficient. Under the servlet architecture, a given servlet instance handles simultaneous requests by spawning a new thread for every request and executing the
service() method within each thread. Figure 1 shows the life cycle of a servlet instance, demonstrating its lightweight scalability.
Figure 1. The servlet threading model
Whether you need to administer a servlet container, set up server load balancing, process a simple HTML form, or even perform complex processing on a stream of HTTP data, the servlet architecture and API make Web application development and deployment quite easy. The setup and administration of a Web server with a servlet container is fairly straightforward, requiring little configuration. Often one or two XML files will contain all the necessary configuration settings for
server deployment. It is also very simple to program a servlet. The servlet API abstracts much of the detail involved in intercepting a client request, routing it to the appropriate servlet instance, retrieving a thread from the thread pool, calling the correct method to handle the request (
doPost(),or any of the others called from the
service() method), and even providing convenient APIs for extracting and processing the
encoded HTTP data.
The case for session beans
The EJB architecture is also designed to provide a flexible, platform-neutral, server-side component model. The EJB specification mirrors the Servlet specification in terms of these features and their implementation. Both technologies provide flexibility through the use of deployment descriptors for deploy-time binding; both are platform-neutral thanks to the JVM and the J2EE spec; and both provide a server-side component model that uses interfaces and abstract classes to reduce development time and hassle, as well as to ensure optimum component reusability. Additionally, stateless session beans reap several benefits from the EJB container, including declarative security, declarative transactional context, configurable relationships with other enterprise beans, and easy integration with other J2EE APIs (such as JMS, JavaMail, and JDBC) through resource-manager connection factories.
Communication with an enterprise bean takes place initially through the bean's home interface, and eventually through the bean's remote or local interface. Since external clients cannot use the local interface, we'll concentrate only on the remote interface. Communication through the remote interface takes place using Java Remote Method Invocation (RMI). This is a Java platform-specific network protocol that allows one Java object to interact with a remote Java object as though it were local. Thus, only Java components (applets, servlets, AWT, Swing, non-GUI Java apps, and so on) can serve as direct EJB clients. Any other client types (such as cell phone, browser, or non-Java app) must communicate through a Java application.
The EJB architecture
From an architectural standpoint, session beans can serve as views, controllers, or even the model itself. They also often implement the Facade pattern or the Business Delegate pattern (see Resources). Session beans can be accessed by a servlet (or JSP page), a JavaBean helping a servlet (or JSP page), another enterprise bean, or directly through an applet, Swing app, or other Java app.
Although the session bean is the most lightweight EJB type by far, the EJB container and EJB architecture come at a cost. An EJB container requires a substantial amount of server power and memory. Unlike the lightweight threading mechanism employed by Java servlets, EJB components require the creation and management of multiple object instances and associated resources (see Figure 2). In exchange for this higher overhead, however, EJB components provide effective management of enterprise resources, transactions, and security checks, without sacrificing much in the way of response times and overall scalability. Because stateless session beans do not have to maintain any client state, they can be efficiently pooled and used to fulfill any client's request.
Figure 2. Enterprise bean management
Whether you need to administer an EJB container, set up server clustering, declare configuration settings for an enterprise bean, or tap into one of the container's many services (including security, transaction management, resource management, and so on), the EJB architecture and API make the development and deployment of robust, full-featured J2EE applications surprisingly simple. Deployment descriptors define the container and bean configurations, and the EJB API uses interfaces, bean life cycle callback methods, and the Factory pattern to provide a clean separation between the container and the enterprise beans, while still allowing bean developers to easily access container services.
Choosing the right technology
Deciding whether to use servlets (or JSP technology), stateless session beans, or both, is very straightforward in some cases and more of an art in others. A typical configuration is to use a servlet layer to handle the interaction with an HTTP client, and then pass off the business processing to the EJB layer (composed primarily of stateless session beans and the occasional entity bean). In this section, we'll look at several typical application scenarios and discuss the best component or components to resolve them.
As you examine these scenarios, keep in mind what you've learned about each technology. In particular, remember that the servlet architecture's lightweight threading model makes servlet scalability particularly efficient, whereas stateless session beans provide an excellent balance between access to robust enterprise resources, good response time, and overall scalability, which is sometimes better suited to more heavyweight applications.
A standard application client is one that interfaces with another system or component rather than a user interfacing with the application. We'll look at three typical application-client scenarios and their most likely resolution:
- If the client is Java-based and behind the same firewall as the server, the optimum solution is to use RMI to talk directly to stateless session beans in the application server.
- If you're working with a non-Java client or a client that is not behind the server's firewall, you'll want to use the HTTP protocol to interface with a servlet. (The decision to go exclusively with a servlet versus a session bean accessed through a servlet should be based on whether or not you need access to the broad enterprise support afforded by EJB components.)
- The third scenario is less common, but it does come up. Some application server vendors have exposed their EJB container in such a way as to accept native IIOP invocations, allowing CORBA clients to treat EJB components as native CORBA applications. This allows a non-Java client to use the IIOP protocol for communicating with stateless session beans. In this setup, the client bypasses the Web tier entirely and communicates directly with the business tier (stateless session EJB components) using the IIOP protocol.
Enterprise application integration (EAI)
EAI involves integrating two or more enterprise applications into a seamless value chain, typically using one or more transactions. Due to J2EE's extensive support for legacy applications, messaging systems, various data sources, and other enterprise applications, it is often used as the glue that pulls various applications together into a cohesive, integrated system.
In the case of EAI there is little contest between servlets and EJB components, since servlets have limited usage in an integration context. In the rare scenario where an application needs to invoke a J2EE method and no other mechanism is available aside from HTTP, a servlet is useful for EAI. Otherwise, it simply poses additional overhead and unnecessary architectural complexity.
Unlike servlets, stateless session beans are well designed for EAI. They are very lightweight (in contrast to stateful session beans), and can be easily pooled to ensure excellent scalability. State management is often needed within EAI, but this can be handled by a proprietary mechanism or by J2EE transactions. Thus, the burden of state management is removed from the application server.
Another possibility is to invoke an EJB component as though it were a CORBA (Common Object Request Broker) component. This is an especially useful option in the case of EAI, where one or more of the applications to be integrated are CORBA components.
Rich GUI client
When it comes to building rich user interfaces to access J2EE server-side functionality, you have several options: applets, stand-alone applications, Java Web Start, and native GUIs.
Applets are loaded as a part of an HTML page, and provide the rich, dynamic user interface that people have come to expect from the Web. (HTML is excellent for displaying text but it makes a lousy user interface.) Applets are powerful in that they are browser-neutral, provide a rich GUI interface, and are prevented by the applet sandbox from accessing local resources without permission. Applets also provide a compelling solution to the problem of updating a client interface: simply install the latest applet class and supporting libraries on the server and the client will download the new files every time the applet is accessed. The price of this flexibility is that the applet class and supporting libraries must be downloaded to the client each time the applet is accessed.
Stand-alone applications are installed directly on an end user's machine. They are not dependent upon a browser and are stored locally rather than being downloaded from a remote site. As a result, they can provide very quick startup and response times. They do not have the security limitations of applets, and thus can more easily access the local client machine and any accessible remote server. On the downside, stand-alone applications are notoriously difficult to maintain and update. Each machine holds a local copy, so it is not possible to automatically update all the applications across a network.
Java Web Start -- essentially a hybrid between applets and stand-alone applications -- is a newer technology that is coming into greater prominence (see Resources for more information). Like an applet, Java Web Start can be invoked from a Web browser and can interact with a servlet. Unlike applets, Java Web Start applications, cache files on the local hard drive and only download additional files when necessary. Java Web Start applications can be installed from a local resource or remotely across the Web. Additionally, the GUI that is launched is a full-fledged Swing client. The browser can be closed without disrupting the application. The result is the best of the applet world combined with the best of the non-applet world. Java Web Start isn't perfect, however. It requires that every resource be contained in a local JAR file (no loose files); it does not allow resources to be accessed directly (they're accessed through an abstract resource-management mechanism); and it does not support the deployment of native applications.
The following solutions are applicable to any of these three rich GUI component types:
- If your client and server are separated by a firewall, you'll want to have your client communicate with a servlet through HTTP. The servlet tier can handle simple business processing using helper classes (parsing XML documents, accessing data sources through JDBC, handling simple messages with JavaMail or JMS, or even orchestrating a simple transaction using JTS/JTA). For more complex requirements, or higher request frequency involving enterprise resources, business processing should be delegated to session beans.
- If your client and server are behind the same firewall, using a straight RMI invocation to talk directly to the application server can increase performance and ease of programming. In this case, servlets simply represent additional overhead and unnecessary architectural complexity. In the case of an applet or Java Web Start, a servlet might be used to initially serve an HTML document with an applet or Java Web Start application link, but afterwards, the client would establish a direct RMI connection with one or more stateless session beans in order to handle client requests.
Finally, if you have a non-Java GUI (that is, native GUI) client that needs to manage a complicated transaction or series of transactions, you'll want to consider the option of invoking an EJB component as though it were a CORBA component.
In the case of a standard, Web-based application (such as a Web browser), you're assuming an HTTP-capable client that needs access to one or more back-end business services. In this case, it doesn't matter what side of the firewall the client is on, and the use of servlets is imperative. The HTTP requirement makes the use of a Web tier a no-brainer. The decision of whether or not to use EJB components behind the scenes will be based on the relative need for EJB container services.
Multiple client types
The final scenario calls for a combination of client types. Perhaps you need a Web-based browser client for external customer use, and a standard desktop, rich GUI for internal use. How do you balance the need for reuse with the need to provide high performance and reliability?
- If you have no need to manage complex transactions, or access multiple enterprise resources, then you can simply use a servlet layer that interfaces with a series of helper classes (JavaBeans) for handling the business processing. The external browser client will interface with your system through this Web layer. The helper beans can then be reused to service the requests of the internal application directly, or the internal app can communicate through the servlet layer. Although this will work, it isn't the most clean, efficient, or scalable solution.
- The more common solution is to put the business logic into stateless session beans, have the external application communicate with the application server through the servlet tier, and have the internal application talk directly with the beans. This creates the cleanest separation between presentation and business logic and allows the internal application direct, unfettered access to the business logic with minimal abstraction to get in the way.
In this first installment of the J2EE pathfinder series, we've explored the relative strengths and weaknesses of using Java servlets and stateless session beans to fulfill client requests. The scenarios discussed here don't cover every situation, but they are representative of some of the most common uses for servlets and session EJBs in a stateless communication context.
Next month, we'll weigh the pros and cons of managing state in the Web tier (using servlets plus
HTTPSession API) versus the business tier (using stateful session beans). Until then, happy pathfinding!
- The J2EE home page is the place to start if you want to learn more about the Java 2 platform, Enterprise Edition and related technologies.
- Brett McLaughlin's EJB best practices series introduces some of the basic patterns and uses associated with Enterprise JavaBeans components.
- Learn more about the Facade, Business Delegate, and Factory patterns mentioned in this article. See Sun Microsystems Enterprise Patterns Guidelines page.
- Paul Monday's excellent "Java design patterns 201" tutorial (developerWorks, April 2002) offers a more theoretical discussion of the use of design patterns in Java programming.
- Sun's Java Web Start home page is a good place to begin learning more about this technology.
- You'll find hundreds of articles about every aspect of Java programming in the developerWorks Java technology zone.
- Also see the developerWorks Java technology tutorials page for a complete listing of free Java technology tutorials.