Introduction to JavaEE packaging
Java Platform, Enterprise Edition or Java EE (which was formerly known as Java 2 Platform, Enterprise Edition or J2EE up to version 1.5), is a programming platform for developing and executing distributed, multi-tier applications. The Java EE platform is made up of a whole host of APIs (with a wealth of acronyms such as JDBC, RMI, JMS) - and they are all defined by Java community specifications. The purpose of this article is not to discuss all of the myriad of technologies at play in a Java EE application but rather to look at what information someone involved in the build and deployment of such applications would typically need to know.
Java EE Packaging
Java EE applications are designed to execute on specific software infrastructure (or middleware) components, an example of a typical infrastructure is illustrated in the diagram below:
In this example we have a multi-tiered application that makes use of (or connects with):
- A Database to store and serve data.
- An existing Legacy System.
- An Application Server to execute the the core business logic (examples of such a server include IBM WebSphere, BEA WebLogic or Apache Geronimo).
- A Web Server to serve requests and execute presentations functions and finally various clients (examples include Apache Tomcat or the IBM HTTP Server). Note that the Web Server can also be "embedded" in the Application Server for smaller applications.
- The various Clients (Internet browsers, desktop applications) that users make use of to operate the application.
There are two important points to realize about such an infrastructure:
- A Java EE application consists of multiple modules that need to be deployed to each of these infrastructure components.
- There are many different vendor supplied infrastructure components that the application could be deployed to.
The first point should naturally get you thinking about complexity - Java EE packaging and deployment is not simple - whilst the second point leads us on to the fact that although Java EE applications are based on standards, there are still vendor specific packaging and deployment steps that might have to be carried out. Given this type of infrastructure, let us look next at how Java EE applications are typically packaged.
Java EE Modules
All Java packaging is carried out using variations of the Java ARchive (JAR) format , this is a ZIP compatible format that allows pre-built Java classes to be bundled together into a module. An optional MANIFEST file can also be included in the JAR that contains meta-data to additionally describe the contents, an example of a manifest file is show below:
Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.0 Created-By: 1.4.2 (The Buildmeister) Built-By: A. Builder Main-Class: net.sourceforge.main.HappyBank Name: net/sourceforge/happybank Specification-Title: "HappyBank Classes" Specification-Version: "1.0" Specification-Vendor: "The Buildmeister" Implementation-Title: "net.sourceforge.happybank" Implementation-Version: "HAPPYBANK_02_REL" Implementation-Vendor: "The Buildmeister"
The manifest file is defined according to a standard and allows you to inject custom information that defines more detail about the archive and could potentially be used at a later date - for debugging as an example. For more information on manifest files see here.
Java EE applications are typically packaged up into an Enterprise ARchive (or EAR file) for deployment. An EAR file is a composite module that is made up of all the modules that need to be deployed to the different tiers. It is still a valid JAR style archive (and the same tools can be used to create and extract it), however it has additional content and it is best to think of an EAR file as a JAR of JARs. A logical example of a typical EAR file is illustrated in the diagram below:
In this example, the EAR file is made up of modules for each of the tiers as follows:
- Web ARchives (or WAR files), that are to be installed into the Web Server
- Enterprise Java Bean JAR files, that are to be installed into the Application Server
- Application Client JAR files, that are to be executed on the Client
- Utility JARs, which are standard Java Archives that the application will make use of
Note that each of these individual modules can be deployed separately, for example a simple Web application might only consist of a WAR file, however complex Java EE applications typically contain the complete set of modules.
In order to describe how each of these module should be deployed on the target infrastructure, each of them has a deployment descriptor. This is an XML file stored in the module that describes the contents of the module, its components and relationships. The standard name of each of these deployment descriptors is shown in light-blue in the diagram below:
In this example as well as the standard deployment descriptors you will notice that there are placeholders for each of the vendor specific deployment descriptors. These have different names from vendor to vendor, however an example of the names used by Apache Geronimo and IBM WebSphere are given in the table below:
|Module||Java EE standard||Apache Geronimo additions||IBM WebSphere additions|
In this table each module has additional vendor specific deployment descriptors (called deployment plans in Apache Geronimo's case). IBM WebSphere has two for the majority of modules, a bindings (bnd) file that binds the abstract contents of the Java EE deployment descriptor to a concrete WebSphere runtime component, and an extension (ext) file that contains extensions that WebSphere provides above and beyond the Java EE standard.
So the questions is what does this mean for the person who has to package all of this together. Well fortunately there is quite a significant amount of tool support that is available to help create and manage the content of these files, examples include:
- Development Environments such as Eclipse, Rational Application Developer or Intelli J IDEA which have wizard and presentation facilities to automate the generation of deployment descriptors and visualize them.
- Programming Tools such as XDoclet which automate their construction based on annotations that you supply in source code (this is an approach that Java EE 5 uses).
- Build Tools such as Apache Ant or Apache Maven which have tasks for creating EAR, WAR and JAR packages.
However despite all of this tool support, the typical Java EE deployment engineer will undoubtedly have to have some understanding of the contents of these files, not just at packaging time but at deployment time - for reasons we will discuss next.
As we have discussed, the technical nature of Java EE deployment will ultimately depend on the infrastructure that is being deployed to, however there are a number of common issues in deployment which apply.
In order for Java EE applications to be built, tested and released organizations typically implement separate run-time infrastructure environments for each part of the lifecycle. An example of the flow of a Java EE application through a complete lifecycle is illustrated in the figure below:
In this example there are four environments: Integration Testing, System Testing, User Acceptance Testing and Production. The number of environments and their names differ from customer to customer, however these are a typical minimum set. Notice that different environments also have different permissions as to who is allowed to deploy to them. In this example a Development Build Engineer would typically be able to deploy to the Integration Testing and System Testing environments, however only an Operations Deployment Engineer would be allowed to deploy to the customer facing environments of User Acceptance Testing and Production.
Since each environment can have multiple servers (e.g. Web, Application, Database), each with different properties (e.g. database names, message queues, user authentication schemes) then it follows that a single Java EE application will need to be configured differently for each one. Some example strategies that can be followed to achieve this are:
- Construct a package for each environment.
- Create scripts that are included in the package and then supply configuration it for each environment at install time.
- Create a single package that contains logical bindings that are resolved at deployment time by an extra configuration file.
The exact approach to be used often depends on the capabilities of the infrastructure that is being deployed to, however most Java EE application servers now support some form of option 3 - for example Apache Geronimo allows you to specify a deployment plan file alongside the EAR file at deployment time. Moving forwards Java EE 5 aims to simplify this process by removing the need for deployment descriptors.
A subtle point to note however, is that since Java EE applications are very flexible in how they can be deployed, often one the main challenge of deployment configuration is obtaining exact information about numbers of servers, distribution, and physical names in each environment so that configuration files can be constructed. One of the ways of mitigating against this is to create a logical deployment model that lists all the application components. This model can then be used in discussions to help elicit the required information.
For Java EE packages to be deployed tool support is needed, there are a number of tools that can be used to achieve this as follows:
- Build or scripting tools such as Apache Ant, Apache Maven, shell scripts and so on.
- Application server specific deployment clients (which often conform to the JSR-88 standard)
- Technology neutral Enterprise deployment and provisioning tools which are available from vendors such as IBM, BMC and Serena Software
Often combined approaches are used, for example scripts are created but they and their associated EAR files are physically moved to servers by an Enterprise deployment tool which then subsequently executes the scripts to perform the install. One of the main reasons why Enterprise deployment tools are used around scripting is that they perform functions such as authentication and access, inventory, guaranteed delivery and rollback that scripting alone could not achieve without significant effort.
In this article I have concentrated on the basics of Java EE deployment - by reading this article you will not be a Java EE packaging and deployment expert. However, you will be aware of some of the issues and best practices that are involved. One of the most important things that you should takeaway is that Java EE application packaging and deployment is not a trivial task and the overall package-test-deploy process is a significant part of an applications development lifecycle. It is recommended that the packaging and deployment is proposed, discussed and implemented early on in the development lifecycle - not when development has almost been completed. Doing so, will mean there are no surprises (which might mean re-development) - or delays (while decisions are made) - in getting your application in the hands of your testers and end-users.
- Professional Apache Geronimo (Wrox Professional Guides)
- IBM(R) WebSphere(R) Application Server for Distributed Platforms and z/OS(R): An Administrator's Guide
- IBM Rational(R) ClearCase(R), Ant, and CruiseControl: The Java(TM) Developer's Guide to Accelerating and Automating the Build Process