Web servers versus application servers
The terms web servers and application servers are often confused by people new to Java EE and used interchangeably, although this is not correct. In this section, we will highlight the differences between the two, as we believe that it is important to know the differences between them, as both are key components of Java EE, but each plays its own role.
Starting to understand the difference between them is best done by highlighting their goals.
Web servers
Web servers implement the Servlet API, which is a set of classes and interfaces defined in the specification that allow you to create dynamic web applications. Applications based on the Servlet API, called Servlets, run inside a web server and serve, possibly dynamic, content to their users.
There are a number of technologies developed over the years that support the Servlet API. Specifications such as Java Server Pages (JSP), Java Standard Tag Libraries (JSTL), Java Server Faces (JSF), and Bean Validations are the most notable. Later, Java API for XML Web Service (JAX-WS) and Java API for Restful Web services (JAX-RS) were added.
There are many popular, standalone implementations of the Servlet API, such as the following:
- Tomcat
- Jetty
- NGINX
All these provide a Servlet container in which servlets can run.
It is good to understand that you can run multiple servlets inside one servlet container. In the early days, this was a common practice, as it allowed you to run more than one application on the same piece of hardware.
For good measure, it should be noted that a framework such as Spring Boot still uses the Servlet API. This means that at the core level, some implementation of the Servlet API is still running. In the case of Spring Boot, however, which servlet container implementation is being used is pluggable, meaning you choose it yourself.
Application servers
Conversely, application servers do have the requirement of supplying an implementation that supports the Servlet API, but they offer far more than that. Application servers offer a richer environment, more targeted at executing business logic. They offer Enterprise Java Beans (EJBs). EJBs come in three major flavors:
- Session Beans (SBs)
- Entity Beans (EBs)
- Message-Driven Beans (MDBs)
Session beans can be further divided into Stateful Session Beans (SFSBs) and Stateless Session Beans (SLSBs). Session beans contain business logic.
Entity beans, which handle database operations, came as Container Managed Persistence (CMP) and Bean Managed Persistence (BMP) entity beans. In the former, the application server was responsible for handling the persistence and retrieval of the data, while in the latter, an application developer had to write the queries to select and update the database themselves.
We write this in the past tense, as entity beans were dropped altogether in version 3 of the EJB specification, delivered in Java EE 5, in favor of the Java Persistence API (JPA).
Furthermore, application servers provide APIs for declarative and programmatic transaction management. As with entity beans, the difference is that in the former, the container will start, commit, or roll back transactions automatically, while in the latter, this has to be done in code.
The Java Messaging Service (JMS) is another feature that is required for application servers. JMS allows you to asynchronously exchange messages between different applications or application components.
JMS offers one-to-one connections between two components via queues while offering a one-to-many message exchange via topics.
Furthermore, application servers allow the registration and discovery of components via the Java Naming and Directory Interface (JNDI). As an example, an EJB to send emails can be instantiated and successively registered in the JNDI registry. Another EJB, which requires the functionality of sending an email, is then able to look up this email service by its name in the registry and use it.
In addition to this, functionality such as declarative security, concurrency, and interceptors are provided by application servers.
Some very popular application servers are as follows:
- IBM Websphere
- JBoss Application
- Oracle Glassfish
- Oracle Weblogic
- Payara Server Enterprise
Application servers had a tendency to be heavy, and startup times were awful. Taking 10–15 minutes to start up and bringing the deployed applications to an initialized state was quite common in the early days. However, nowadays, it is very common that they start within a few seconds.
Profiles to the rescue
In the early years of Java EE, there was one simple rule if you wanted to be a Java EE compatible server – you had to implement all the specifications. However, it soon became clear that not every application required a full-blown application server. Often, a web server was more than enough.
To make this distinction clearer, profiles were introduced. The first one was Web Profile, which made its first appearance in Java EE 6. It was made up of the Servlet, JSF, JSP, EJB, CDI, JTA, JPA, and Bean Validation specifications.
The full set of all specifications became known as the Full Platform Profile.
In Jakarta EE 10, the Core Profile was introduced. This contains an even smaller subset of specifications and targets microservices, edge-computing, and ahead-of-time compilation. In Chapter 2, we will dive deeper into these subjects.
The following diagram depicts the different profiles and the specifications they are required to implement. The image was taken from the Jakarta EE website (https://jakarta.ee/release/10/).
Figure 1.1 – The different Jakarta EE profiles and their specifications