Is Tomcat enterprise ready?

Learn where Tomcat fits, and doesn't, in your enterprise

When Java developers start talking about application servers, Tomcat is often thrown into the mix. After all, it's one of the most popular options for lightweight development scenarios, and in many cases meets the need for an application server, even though it is technically a Web server. In this article Jeff Hanson engages the question of whether Tomcat is an app server, first by explaining what differentiates application servers, Web servers, and Java EE containers, and then by evaluating Tomcat's suitability to a variety of common Java enterprise development scenarios.

Confusion over whether Tomcat is an application server tends to result in heated discussion among Java developers -- some claiming it absolutely is and some that it definitely is not. In truth, Tomcat often is used as an app server, and for some scenarios it is perfectly suited to that role. For developers using Tomcat as an app server, it makes sense to classify it as such, regardless of formal definition.

In this article I tackle the question of whether Tomcat is an application server. I start by explaining the distinctions between app servers, Web servers, and Java EE containers, and then look at some scenarios where a Web server like Tomcat could be used appropriately as an app server. I show a scaled architecture, starting with the sort of lightweight implementation where Tomcat shines, and concluding with a complex service-oriented architecture, where you would be better off with a full-fledged Java EE application server.

Java EE as a point of reference

Java Platform, Enterprise Edition, or Java EE, is the de facto standard for developing server-side Java applications. As such it is the foundation on which all other server-side Java technologies, including app servers, must rest. Java EE compliance is an essential factor when evaluating the difference between Web servers and application servers.

Java EE extends Java Platform, Standard Edition (Java SE) to support Web services, an enterprise component model, management APIs, and communication protocols for designing and implementing service-oriented architectures, distributed applications, and Web applications. (Note that Web applications are only one sector that Java EE seeks to support.)

A compliant Java EE application server must support features such as an Enterprise JavaBeans (EJB) server and container; JNDI capabilities; a Java Message Service (JMS) framework; a Java Transaction API (JTA) framework; and J2EE Connector Architecture. Java EE servers usually support a hierarchical classloader architecture enabling such functionality as EJB loading/reloading, WAR loading/reloading, manifest-specified utilities, and so on.

Java EE defines containers for client applications, servlets, and EJB components. These containers provide structure and functionality that facilitate the deployment, persistence, and execution of supported components.

Java EE also defines a standard architecture for connecting Java EE applications and application servers to heterogeneous Enterprise Information Systems, such as ERP systems, mainframes, database systems, and non-Java legacy applications. The J2EE Connector Architecture enables a provider of an enterprise system to expose the system using a standard interface known as a resource adapter. The resource adapter allows an application server or enterprise application to use the same interface for different enterprise system vendors. Resource adapters operate within the address space of a host application server.

Figure 1 shows the tiers and components of a typical Java EE application architecture.

Illustration of a typical Java EE application architecture.

Figure 1. A typical Java EE application architecture (click to enlarge)

A Java EE application server is needed to support some, but not all, of the components shown in Figure 1. Using a Java EE server gives you the convenience of hosting a system in a pre-tested environment that offers all of the Java enterprise development services. In some cases, however, the Java EE server brings unnecessary overhead to an execution environment that only requires one or two of these services.

For instance, many Java-based Web applications are deployed to environments that only support the technologies found in a Web server/container, such as servlets, JSPs, and JDBC. In these scenarios you might choose to construct a system piecemeal, using sundry frameworks and providers. Some developers would choose to use Tomcat in place of the Java EE application server given these environmental constraints.

Oftentimes the decision of whether to use an application server or Web server depends on the type of communication needed between application components, so let's consider those options next.

EARs, WARs, JARs, and Java EE

A Java EE application may contain one or more Java EE components such as EJBs, Web modules, resource adapters, or J2EE application client modules. Each Java EE component can have an associated deployment descriptor -- an XML file that describes the component. Java enterprise components are deployed using the Java Archive (JAR) file format, which branches into additional formats to handle various component types.

The Java Archive (JAR) file format is based on the ZIP file format and enables you to bundle multiple Java EE components into a single file. A JAR file can contain Java class files, XML descriptor files, auxiliary resources, static HTML files, and other files associated with each Java EE component. A standard Java Web application is deployed in a Web Application Archive (WAR) file, which is a JAR file with the extension of .war. A standard Java EE application is deployed in an Enterprise Application Archive (EAR) file, which is a JAR file with an extension of .ear.

A WAR file is a specialized JAR file containing Web application components such as servlets, JSP files, HTML files, deployment descriptors, utility JAR files, etc. A WAR file can be deployed to a Web server such as Tomcat.

An EAR file is a specialized JAR file containing Java EE application components such as Web applications (WAR files), EJBs, resource adapters, etc. An EAR file can be deployed to a Java EE application server such as JBoss, WebLogic, or WebSphere. Java EE application servers load EAR files at runtime and deploy the components found within each file as Web applications, resource adapters, EJBs, and so on, based on the instructions found in each component's deployment descriptor.

Figure 2 illustrates the components found in many typical Java EE application server deployments.

Diagram of the components found in many typical Java EE application server deployments.

Figure 2. Components of a typical Java EE application server deployment

An EAR file can contain multiple Web applications along with other resources and auxiliary components. Deploying an application as an EAR file within the structure of a Java EE application server environment enables the app server to isolate each Web application within a separate class-loading and resource-loading context. Web applications in the Java EE app server environment can share resources in common, such as utility class files.

In a Java EE environment, specialized containers are designated to handle component isolation and resource sharing. These containers are, in turn, managed by the application server. Containers provide an isolated context wherein Java EE components are deployed and execute. Containers provide an abstraction layer between the components, ensuring that they seldom interact directly. Instead, components can use the protocols and APIs of the container to interface with each other and with other application services. This layer of abstraction enables containers to provide ancillary services required by the component, such as pooling, transaction management, and state management.

Web applications vs. enterprise applications

For some, the confusion over Tomcat's definition points to the deeper question of what differentiates an enterprise application from a Web application. Traditionally, a Java enterprise application is defined as a combination of the following components and technologies:

  • EAR files
  • Java Servlets
  • JavaServer Pages or JavaServer Faces
  • Enterprise JavaBeans (EJB)
  • Java Authentication and Authorization Service (JAAS)
  • J2EE Connector Architecture
  • JavaBeans Activation Framework (JAF)
  • JavaMail
  • Java Message Service (JMS)
  • Java Persistence API (JPA)
  • Java Transaction API (JTA)
  • The Java Management Extensions (JMX) API
  • Java API for XML Processing (JAXP)
  • The Java API for XML-based RPC (JAX-RPC)
  • The Java Architecture for XML Binding (JAXB)
  • The SOAP with Attachments API for Java (SAAJ)
  • Java Database Connectivity (JDBC) framework

A Java Web application, meanwhile, is said to combine a subset of Java enterprise application components and technologies, namely:

  • WAR files
  • Java Servlets
  • JavaServer Faces or JavaServer Pages
  • Java Database Connectivity (JDBC) framework

Popular frameworks such as Apache Struts, Spring, Hibernate, and others have obscured the traditional distinctions between Java enterprise and Java Web applications. Each new framework offers a slightly different view of how to accomplish the same tasks. Each framework attempts to solve a given set of challenges in a more efficient manner, possibly using a different set of underlying technologies.

Perhaps, this obscurity might be cleared up by observing the behavior of components deployed within different scenarios for a typical Java-based enterprise/Web application. These scenarios are discussed next.

Java EE application scenarios

In a typical Java EE Web application, an HTML client posts a request to a server where the request is handled by the Web container of the application server. The Web container invokes the servlet that is configured to handle the specific context of the request.

The initial HTML client request is illustrated in Figure 3.

An HTML client posts a request to an application server.

Figure 3. Initial HTML client request

Once the servlet has received the initial request, some form of request dispatching ensues in order to perform the necessary business logic for completing the request.

One or more business services or components are then invoked to perform business logic, as illustrated in Figure 4.

Business services or components are invoked to perform business logic.

Figure 4. Business services or components in the JEE architecture

Most business services or components require access to some form of data storage or information system. Oftentimes an abstraction layer between the business service and the data store is provided in order to protect against future changes in the data store. DAOs (data access objects) are often employed as data abstraction components in this situation, as shown in Figure 5.

One or more DAOs are invoked to perform business logic

Figure 5. DAOs are invoked to perform business logic (click to enlarge)

When the DAO invocation step is complete, the response data is passed back up the chain of command, usually as one or more Java beans. The Java beans are then passed to some type of state machine and/or view manager in order to organize and format the markup response.

When processing is complete for a given request, a formatted response is passed back to the HTML client, as illustrated in Figure 6.

A formatted response is passed back to the HTML client.

Figure 6. A response is passed back to the HTML client (click to enlarge)

The scenario depicted in Figure 6 can be implemented using a very limited set of Java EE technologies, including servlets, JDBC, and JSP or another view technology. Tomcat or any Web server providing a servlet engine and JSP engine could be used as the app server in this scenario.

Scaling into complexity

Now, suppose we add a requirement to the application for asynchronous messaging between business service components. In a Java-based system, this would typically be handled using the Java Message Service (JMS), as shown in Figure 7.

JMS handles asynchronous messaging between business service components.

Figure 7. JMS handles asynchronous messaging between business service components (click to enlarge)

Most Web servers do not offer JMS as a standard feature, but it is simple enough to add a JMS implementation to a Web server environment. So, once again, the application scenario depicted in Figure 7 could be handled quite easily with just a Web server providing a servlet engine and JSP engine.

Next, suppose we add the requirement for connectivity between business services and disparate enterprise information systems. Java EE offers the Java Connector Architecture as a common standard to meet this challenge. Using the Java Connector Architecture, the application architecture evolves to something similar to what you see in Figure 8.

The Java Connector Architecture handles connectivity between business services and EISs.

Figure 8. JCA handles connectivity between business services and EISs (click to enlarge)

The architecture is now approaching a complexity that is arguably better suited for a Java EE application server. A Web server such as Tomcat could possibly be used in combination with other frameworks to meet the requirements, but system management and monitoring complications might make the server/framework mix impractical.

Finally, Figure 9 presents a moderately complex, Java-based, service-oriented architecture employing all of the technologies discussed so far, along with communication between multiple WAR deployments, EJBs, and Web services.

Diagram of a moderately complex SOA.

Figure 9. A moderately complex service-oriented architecture (click to enlarge)

The architecture in Figure 9 has entered the realm of complexity that requires a tested, scalable, manageable Java EE enterprise application server. Once again, a development team with the proper skill level could use Tomcat for the Web tier and piece together technologies and frameworks to support the business and data tiers. Whether that effort would be well spent is questionable, particularly given the option to use a full-fledged application server.

Using Tomcat as an application server

Building scalable solutions

It is not uncommon for Java enterprise applications to scale along the lines suggested by the example in this article, growing in complexity as new requirements are added. While Tomcat (or any Web server) might suit your initial application requirements, it could become problematic in the long run, as the system gradually requires more complex deployment, management, and monitoring solutions. A Java EE application server is more scalable than a Web server, providing tight integration between containers and deployment contexts for each additional technology. In many cases, choosing a Java EE app server is the more cost-effective solution for the long run.

As the evolving application example in the previous section shows, Apache Tomcat can be used as an application server, especially for less complex Java EE Web applications. According to some figures, Tomcat is the Web/application server environment most used by Java developers. Tomcat's popularity is due to its ease of use and support for many features considered to be standard in a Java Web application environment, including WAR file deployment, JNDI resources, JDBC data sources, JSP support, session replication, virtual hosting support, clustering support, and JMX-based management and monitoring. Tomcat is also a favorite for Java enterprise development due to the fact that its runtime performance as a standalone server is very competitive.

With Tomcat version 6, some new features have been added including asynchronous HTTP request handling via Comet, thread pool sharing, non-blocking connectors, enhanced JMX management and monitoring, Servlet 2.5, and JSP 2.1.

Even with these new features, however, Tomcat does not support the entire Java EE stack. Where Tomcat and other Web servers fall short is in the area of features such as distributed transactions, EJBs, and JMS. Applications requiring support for these components are usually more at home in with a Java EE application server such as JBoss, Geronimo, WebLogic, WebSphere, or Glassfish. Many Java EE application servers actually use Tomcat as their Web container.

In conclusion

The formal distinction between Java EE application servers and Web servers is clear, but the real-world distinction is less obvious. While Tomcat is not strictly speaking an application server, this article has shown that it works quite well in that capacity, up to a point.

When attempting to determine the server environment best suited to a particular application or system, it is helpful to break down the requirements of the system and determine which Java EE components will need to be supported. For simpler Web applications that will not scale much, Tomcat is a fast, reliable, lightweight solution. For more complex enterprise applications, SOAs, or even highly scalable Web applications, a full-fledged Java EE application server is usually the more cost-effective choice.

About the author

Jeff Hanson has more than 20 years experience as a software engineer, including working as senior engineer for the Windows OpenDoc project and as chief architect for the Zareus SOA platform. The author of numerous articles and books, he is the chief architect for Max Software Inc., where he leads design and implementation teams building desktop and server applications for the content-control industry using C++, PHP, and JEE.

All contents copyright 1995-2011 Java World, Inc. http://www.javaworld.com