An application server is a software stack that provides the business logic of a large-scale distributed application. These business logic and business processes are used by other applications running on other computers or that may be running on the same computer. Application servers are used in scenarios where very complex transaction-based applications are continuously running. For the success of any business application, the optimal performance of these servers is very critical. Today, almost all organisations have their own application servers that provide the business processing logic to their applications.
If you look at how Wikipedia defines an application server: “An application server in an n-tier architecture, is a server that hosts an API to expose business logic and business processes for use by third-party applications. The term can refer to:
- The services that are made available by the server
- The computer hardware on which the services are deployed
- The software framework used to host the services such as the JBoss application server or Oracle application server.”
The general architecture of an application server is shown in Figure 1.
The most desirable features of an application server are:
- Data integrity
- Load balancing
- Centralised configuration
- Code integrity
- High performance
A list of well-known open source application servers are:
- GlassFish (available under Common Development and Distribution License and the GPL)
- JBoss (GPL)
- JonAs (GPL)
A notable exception in the above list is Apache Tomcat. It is a topic of continuous discussion among Java developers on whether this is an application server or a Web server. The classification actually depends upon how it is used. Refer the JavaWorld article on Tomcat for an interesting discussion.
In this article I am going to focus on GlassFish, which is a community-driven project started by Sun Microsystems in June 2005. I will present this article in two parts, the first of which will explain the basics about application servers and the architecture of GlassFish. In the second part, I will cover getting started with GlassFish on Linux.
The foundation of the GlassFish community
GlassFish [glassfish.dev.java.net] is a community driven project to develop an open source productive Java EE 5 application server.
The base code of the project is donated by two industry giants:
- Sun Microsystems—Sun Java System Application Server PE 9
- Oracle—Top Link Persistence
The architecture of GlassFish
The GlassFish community describes the design goal of GlassFish as:
- To make an open, modular, extensible platform
- A fast, easy, reliable application server
- An enterprise-ready application server with massive scalability and sophisticated administration
- Product updates and add-ons through the industry-strength Update Centre 2.0
- Support for OSGi
- Support for dynamic languages such as Ruby and Groovy
- Support for Java EE 6
Let us go on to explore the overall design architecture.
A modular subsystem
In enterprise development, where large scale distributed applications are continuously running, there is a strong need for isolation between various parts of an application. This is required because if any part of a large scale distributed application crashes, the whole system should not crash. Therefore, any application server ideally should be an assembly of modular sub-components.
The modular subsystem for GlassFish is based upon the Hundred KiloByte Kernel. Generally known as HK2, it is a sub-project under the GlassFish Community. If we look closely at HK2, it is based on two technologies:
- Modules Subsystem, and
- Component Model
Modules Subsystem is responsible for instantiating various classes to provide application functionality and the Component Model is built upon the Modules Subsystem.
Component Model works very closely with Modules Subsystem and it configures the various objects created by the Modules Subsystem—for example, bringing in other objects that are required by the newly created object, providing the newly-created objects to other existing objects, etc.
The GlassFish wiki defines the module management system as ‘a distribution artifact’. A distribution is a collection of various modules and an artifact is a file that contains the distribution. GlassFish v3 will be available in various distributions. Just as today we have various distributions of GNU/Linux, each with its own set of features, similarly, various distributions of the GlassFish application server will have various modules and distinct features. Module management depends upon Maven—a Java project management tool.
To add your module in a distribution, you have to follow these three steps:
- Compile your module from its source code.
- Create a file that contains the module.
- Add the module’s identification in the distribution list.
The GlassFish Application server is designed as a set of modules. It has no main class for its start up. Instead, it has a bootstrap module that is first loaded by the Class Loader. The bootstrap module loads other modules that are required. Also, care has been taken so that the bootstrap module does not load all the modules at the start time. But suppose the modules have been programmed such that when they are loaded they refer to each other, then all the modules will be loaded at the start time, which will kill the basic aim of a modular designed server. To solve this problem, GlassFish uses a technique by which programmers are prevented from directly programming with modules. GlassFish uses a concept of service. These services are classes that implement an interface. And programmers are encouraged to program on these well-defined services instead of programming with modules.
Persistence is one of the most critical service given by an application server to the applications running on it. GlassFish has a lot of design challenges for its persistence service, mainly due to the old issues involved in the persistence mechanism. Java EE programmers have always seen various implementations of
javax.persistence API, which have issues with the old JDBC classes and their usage.
According to the GlassFish wiki, the following patterns were identified while designing persistence in GlassFish:
- Applications can do a
Class.forName( )call to load a JDBC driver and make direct calls through the JDBC APIs to the underlying database. Applications do not need to identify a special interest in such drivers. There is also no indication they will use such low level access APIs.
- Applications can decide to use the default JPA provider, letting GlassFish choose which one to use.
- In Java SE mode, applications can use the
PersistenceProvider.createEntityManagerFactory()call to get a specific persistence provider (name extracted from the
- In Java EE mode, GlassFish is responsible for loading the
persistence.xmlfile, and looking up the expected persistence provider according to its settings (potentially defaulting the provider name).
- In Java EE mode, GlassFish is responsible for identifying the connection pool to be used with the entity manager. This resource adapter is retrieved at deployment time from the JNDI name space and wired up with the persistence provider to create the entity manager.
Containers are the heart of an application server because they are the entities that run an application. For example, the EJB container in an application server is responsible for running Java EJB applications. This EJB container provides various additional features for Bean developers like security, scalability, client interaction and a messaging service. Thus, an application programmer is only concerned with implementing the business logic; all the other stuff is handled by the container. Containers are always created as pluggable units, such that they can be installed or removed from the application server.
According to the GlassFish wiki: “Containers have the ability to install themselves in an existing GlassFish installation with the following services implementations:
- Sniffer: Invoked during a deployment operation (or server restart). Sniffers will have the ability to recognise part (or whole) application bundles. Once a sniffer has positively identified parts of the application, its set-up method will be called to set up the container for use during that server
- ContainerProvider: This is called each time a container is started or stopped. A container is started once the first application that’s using it is deployed. It will remain in operation until it is stopped when the last application using it has been stopped.
- Deployer: This is called to deploy/undeploy applications to a container.
- AdminCommand: Containers can come with a special set of CLI commands that should only be available once the container has been successfully installed in a GlassFish v3 installation. These commands should be used to configure the container’s features.”
The promise of the GlassFish community is to make a production-quality application server and add new features to it faster than even before. The following are the key features of the GlassFish Application server:
- Production quality
- Has load balancing
- Delivers more work with less code
- Issue tracking
- Service-oriented architecture
- Tools integration
- Ease of container pluggability
And one of the most important features is that, being an open source project, we have access to the source code and can understand the bits and bytes of an enterprise-class application server.
In my next article I will explain how to get started with GlassFish. Additionally, I will also develop a simple Java enterprise application using GlassFish.