Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


EJB 2 and J2EE Packaging


Have you noticed the number of different types of JAR files that you have to deal with lately in J2EE?! JAR files do not just hold EJBs anymore. Rather, JAR files are being used to store utility classes, web applications, enterprise applications, and Java Connector Architecture (JCA) resource adapters. Additionally, in some scenarios, some JAR files are composed of other JAR files.

Now that most major application servers are supporting dynamic class (un)loading with custom classloaders, what are the issues J2EE developers face when working with all of these packaging technologies? This article discusses some of the nuances associated with J2EE packaging and provides some hints to make you more productive.

The First Issue: EAR Support for Limited Components

Currently, the J2EE 1.3 specification defines an enterprise application packaging unit to be a JAR file with an .ear extension. EAR files can contain one or more:

Since most web-based J2EE applications are composed of web and EJB applications, the EAR file meets the basic requirements for packaging an application. However, it is lacking in capability for packaging complicated J2EE applications. For example, the following components are often used in a J2EE application, but cannot be declared in an EAR file:

Currently, all of these components of an application have to be manually configured and deployed through a vendor's administration interface. As the usage of the items listed above increases over time, it will become more important for EAR files to natively support packaging of these components to achieve true J2EE application portability.

The Second Issue: Utility and Support Classes

Comment on this articleGive your questions to Tyler Jewell.
Post your comments

Also in EJB 2:

Unlocking the True Power of Entity EJBs

Stateful Session EJBs: Beasts of Burden

EJB 2 and J2EE Packaging, Part II

EJB 2.0 Specification Release Review

Sorting Out the EJB 2.0 Rumors

The most frequent question raised about J2EE packaging is in regards to utility and support classes. When packaging a web application or an EJB application, where should you place these libraries?! If you place these classes into the standard CLASSPATH of your application server, they will likely lose any unloading ability that Web/EJB applications have that are driven by special classloaders used to load them at deployment. If your Web/EJB applications need to change the version of the libraries that they use, then the dependent library will need to be re-deployed when the Web/EJB application is re-deployed. In this scenario, storing utility classes on the standard CLASSPATH is not a feasible option, since the entire application server would have to be restarted for each deployment of a Web/EJB application. (Yuck!)

Given the standard definition of J2EE, where are you supposed to place libraries so that they can be re-deployed with an application at runtime? I've seen some creative, yet undesirable, solutions:

The second solution is admittedly gross:

A Solution

So what is the right solution to this dilemma? One of the possible solutions is to eliminate the need for multiple JARs in your J2EE application by converging all of your EJBs and their utility classes into a single, unified package. The EJB 2.0 public final draft 2 (PFD2) specification is driving some projects to do this. This new version of the specification mandates that entity EJBs participating in a relationship do so using local interfaces and requires both of the EJBs in the relationship to be packaged into the same JAR file. PFD1 allowed EJBs in different JAR files to participate in relationships, further promoting greater modularity of the system, but ultimately limited the persistence optimizations that containers could do for CMP entity beans in a relationship. Now that PFD2 eliminates this capability, many vendors are providing tools that perform EJB JAR convergence. These tools will take as input two valid EJB JAR files and merge their contents and deployment descriptors into a single, unified package. You could potentially use one of these convergence tools to re-package your existing JAR applications.

Keep in mind that even if you converge all of your EJBs into a single JAR application, you will have eliminated copies of your utility library among the EJBs, but a copy will still exist in your WEB-INF\lib library. Additionally, the need for modularity of EJB applications still exists, since many companies desire to re-deploy EJBs on an individual basis. Since every EJB in a JAR will be re-deployed when that JAR file is re-deployed, an unnecessary amount of deployment processing could occur if your only desire is to re-deploy a single EJB.

A Better Solution

With the release of JDK 1.3, Sun Microsystems redefined the "extension mechanism," which is the functionality necessary to support optional packages. The extension mechanism is designed to support two things:

Additionally, the J2EE 1.3 specification's section 8.1.2 mandates that compliant application servers must support the extension mechanism as defined for JAR files. This requires that any deployment tool that references a JAR file be capable of loading any optional libraries defined through the extension mechanism. This also implies that if an application server or deployment tool supports runtime undeployment and re-deployment of EJB applications that use libraries via the extension mechanism, then that tool or application server must also support undeployment and re-deployment of any dependent libraries!

Support for the extension mechanism does not exist for EAR, WAR, or RAR applications as defined in the J2EE specification, since these applications are not directly loaded by a ClassLoader instance. Web applications still have to have libraries packaged in the WEB-INF\lib directory and resource-adapter applications can have libraries bundled directly in the RAR file. Enterprise applications will need to package any libraries within the Web, EJB, or resource-adapter application that requires them. So how does the extension mechanism work with EJB applications? A JAR file can reference a dependent JAR file by adding a Class-Path manifest attribute. The Class-Path manifest attribute lists the relative URLs to search for utility libraries. Multiple URLs can be specified in a single Class-Path entry and a single JAR file can contain multiple Class-Path entries. For example, a JAR file might have:

Class-Path: log4j.jar xmlx.jar foo/bar/util.jar

NOTE: If you use the extension mechanism in a J2SE application, the Class-Path manifest entry can reference directories, too. But for J2EE applications that are wholly contained within JAR files, the Class-Path manifest entry can only reference other JAR files.

The extension mechanism is a nice capability, especially since it is designed to handle circular redundancies by creating a unified class path containing all dependencies in first parsed-based ordering. For example, if the first EJB application parsed is EJB1.jar and it references:

Class-Path: jaxp.jar EJB2.jar xmlx.jar

A classloader will then parse EJB2.jar that references:

Class-Path: jaxp.jar EJB1.jar

The resulting "application" class path that a classloader would ultimately use would be:

Class-Path: jaxp.jar EJB2.jar xmlx.jar EJB1.jar


The manifest class path will definitely spur better modularity of J2EE packages in the future. Using this model, developers can employ a simple scheme for determining which EJBs should be packaged into a single JAR file and which should be packaged in separate JAR files:

  1. Identify an entity EJB that participates in a CMR relationship. Identify all entity EJBs that are reachable via CMR relationships from the source entity EJB. This graph of entity EJBs must be packaged into a single JAR application. Repeat this process for each unique graph of entity EJB relationships
  2. Package all remaining EJBs into separate JAR files.
  3. Analyze your business and technical requirements and "converge" multiple JAR files if it makes sense.
  4. Each EJB JAR file should list its dependencies using the manifest class path attribute, as described above. An intelligent classloader will resolve any circular or repeating dependencies.

The only limitation that developers are now faced with is locating an application server that fully supports this packaging capability. Developers will need to look for application servers that run in a 1.3 JDK and fully support section 8.1.2 of J2EE 1.3. Without this support, developers will need to fall back to one of the other, less-desirable solutions posted in this article. Happy packaging!

Tyler Jewell , Director, Technical Evangelism, BEA Systems Tyler oversees BEA's technology evangelism efforts that are focused on driving early adoption of strategic BEA technologies into the ISV and developer community.

Read more EJB 2 columns.

Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.