Contents
IntroductionMany Java 2, Enterprise Edition (J2EE) applications use utility classes or libraries that provide some extra functionality not supported by the application code or the J2EE platform APIs. Often these libraries are placed in a Java Archive (JAR) file so that they can be used by multiple applications. These JAR file libraries can be created by the application provider or obtained from a third party. The J2EE platform supports the common use case of an application's using a library that is provided to the application code. This article
Application portability is an attractive aspect of the J2EE platform. The Java Blueprints program and the Java Application Verification Kit (AVK) for the Enterprise were put in place to help developers write portable J2EE applications, and both are free and available for use. The Java AVK for the Enterprise is designed to identify enterprise applications developed with J2EE technology that are intended to be portable across different implementations of the J2EE platform. It includes a set of tools intended to help developers test their applications for correct use of J2EE APIs and portability across J2EE compatible application servers. You can use the Java AVK for the Enterprise to test your application for portability problems. The Java BluePrints program provides an extensive set of guidelines, design patterns, and sample applications that serve as models for developers writing portable applications. In particular, the Java Adventure Builder Reference application showcases how to design interoperable and portable web services on the J2EE 1.4 platform, and the Java Pet Store Sample Application shows how to use the capabilities of the J2EE platform to develop robust, scalable, portable, and maintainable enterprise applications. We recommend that anyone implementing a J2EE application study these applications. ScopeThis article focuses primarily on static dependencies in the application code and the mechanisms to handle those dependencies. Some applications have dynamic dependencies where these mechanisms do not need to be used. An example of static dependency is an application that uses a logging library to display progress and error information to the user. This library is required for proper execution of the application, and therefore the application needs to specify a dependency using one of the mechanisms described in Mechanisms for Using Libraries in J2EE Applications. As an example of a dynamic dependency, consider an application that uses a logging package. The application can abstract away which logging implementation it is using. When the application starts up, the logging package configures itself as follows (unless you explicitly configure a hard-coded choice):
In this example, the dependency is resolved at runtime, and the
We use the term library to mean a collection of classes that is packaged using the Java Archive (JAR) utility. These classes may be developed externally as third-party code or as utilities within the organization. Typically, they provide useful general-purpose functionality to many different applications. If you are already familiar with the mechanisms in the J2EE platform for portable packaging of library JAR files, feel free to skip to Scenarios, where the mechanisms are applied to various application packaging scenarios.
The following are some common situations in which you would want
to use library code:
Once you have decided to use one of these libraries, you face the important design decision of how to package these extra libraries along with the application code. The decision you make can have major effects on the following:
Mechanisms for Using Libraries in J2EE ApplicationsFor portable applications, there are several mechanisms in the J2EE
platform to support using optional packages such as a library or
utility JAR file.
These mechanisms are reviewed briefly in this section. For each of
these mechanisms, you need to determine where to place the library JAR
file and how the referencing application files (which may be JAR, EAR,
WAR, or RAR files) can indicate where the library JAR file can be
found, either through an explicit reference or by placing it in a
well-known location such as
Overview of Mechanisms to Support Optional PackagesSome solutions for packaging library JAR files are specific to a particular application server: for example, placing a library JAR file in an application server's classpath so that applications can use the APIs in that JAR file. Some application servers have container-specific locations where you can place JAR files to be shared by applications and modules. But these mechanisms are not portable, unlike the mechanisms provided by the J2EE platform. This section describes the portable mechanisms for using optional packages such as library JAR files. Some of these mechanisms are specific to the J2EE platform, while some use the Java 2 Platform, Standard Edition (J2SE) extension architecture mechanisms for handling optional packages. For detailed descriptions of these mechanisms, see References at the end of this document. Some application servers allow for mechanisms beyond these portable mechanisms. Often, placing a JAR file in a certain location will allow an application to deploy and run. But it is best to use the portable mechanisms described below. Mechanism 1: The WEB-INF/lib DirectoryIf you place a library JAR file (for example, This mechanism cannot be used by EJB modules. Mechanism 2: Bundled Optional ClassesUse the
The J2EE 1.4 platform specification states that top-level JAR files,
such as EAR files, should not contain
Here is an example for an EAR file containing a web module that uses Struts:
Mechanism 3: Installed PackagesUse the When you use this installed packages mechanism, the library JAR file is available to all applications.
Here is an example (from the J2EE 1.4 Platform Specification) where the
file
Brief Description of the J2SE 1.4 Extensions for Optional PackagesThe J2EE 1.4 mechanisms for portably packaging library JAR files use the J2SE mechanisms for allowing applications to use libraries packaged as JAR files. This section briefly reviews some of these concepts. Note that optional packages is the new term for what used to be known as standard extensions or just extensions. The J2SE platform allows optional packages in the following two ways (paraphrased from the Optional Packages Overview document):
Checking that Your Application Is Packaged CorrectlyThe Java AVK for the Enterprise provides tools to scan an
application archive for incompatibilities with the specification,
correct use of APIs, and
packaging rules. The Ant task
You must create a
Below is the part of the report that shows the failure found by
static
verification because the archive was not packaged correctly. Here
the classes
Static verification reports the problem as follows.
To correct this error using the bundled optional classes mechanism, the
manifest file in
You can use a command like the following to update the
Once this version of ScenariosThis section examines how the mechanisms for portably packaging an optional package provided as a library JAR file can be applied to some common scenarios for J2EE applications. These scenarios are based on the questions most commonly asked by users. Scenario 1: The application is a stand-alone WAR file that uses one or more library files. The application consists of a WAR file that is not packaged in an EAR file. In J2EE 1.4, a stand-alone module such as a WAR file is a valid J2EE application, and no EAR file wrapper is required.
In this case, you can use the
The bundled optional packages mechanism would not work, because the WAR file in this case is a top-level application file (a stand-alone WAR or EAR file) and top-level application files must not have a
The installed optional packages mechanism would work. For example, a library JAR file such as Scenario 2: The application is an EAR file that contains more than one web module (WAR file), and you want these web modules to share the same library JAR file rather than bundle duplicate copies of the library. For example, suppose you have an EAR file with two WAR files, both of which use Struts, and you want them to share the
In this case, you can use either the bundled optional packages mechanism or the installed packages mechanism. You cannot use
the
For the bundled optional packages mechanism, each web module uses the manifest file and
For the installed optional packages mechanism, each web module uses a manifest file and Scenario 3: Multiple applications (different EAR files and/or different stand-alone WAR files) need to share the same library JAR file. In this case, you want multiple applications to use the same library, and you do not want to include duplicate copies of the library JAR file in each application. For example, multiple applications may need to use the same version of the JSTL tag libraries. This case covers applications that are deployed as EAR files or as stand-alone WAR files.
In this case, you can use the installed optional packages mechanism. Put one copy of the library (for example, Scenario 4: For developers of libraries intended to be used and packaged with applications. In the previous scenarios, a developer is creating an application that uses libraries in a portable way. But what if you are a developer of a
library, such as Struts or JSTL or utility classes, that must be portable among different J2EE 1.4 application servers? In particular, what if the library you are creating has dependencies on some third-party code? (For example, JSTL uses a specific version of
According to the J2EE 1.4 platform specification (Sections 8.2 and
8.4), if you want to create a JAR file to be used as an optional
package, it should be packaged as a
If your library does have dependencies on external code, use one of the three mechanisms described in the section Mechanisms for Using Libraries in J2EE Applications. The writer of the library is bound by the same rules and mechanisms as the user of the library code. Issues and RecommendationsThe J2EE 1.4 Platform Specification is vague about how to handle multiple versions of a library. The classloader can be different in the various application servers, so libraries can be handled inconsistently. The best way to guard against this problem is to have a policy for handling versions of libraries. Before discussing the policies that application developers should use, we need to go over the policies the server vendors use to load classes. One such policy involves precedence order. What if an application EAR file uses more than one mechanism to reference a library in its packaging? Or what if multiple versions (or multiple copies of the same version) of a library JAR file are present? Which instance of the JAR file would be used at runtime by the application? The order of precedence in the J2EE and J2SE platforms may be different, and the J2EE platform specification applies to applications deployed on application servers. The J2EE platform specification recommends a precedence order for resolving the finding of an optional package. Generally an application server will look for a class in a library JAR file in the following order:
If a class cannot be found, the application is not deployed. Application servers often will not allow a library JAR
file to replace a platform API, so, for example, an inclusion of your
own
Application developers should define and follow policies to help ensure that their applications work as expected on the different servers. Policies should assume that the application server follows the loading steps recommended in the platform specification, as described above. Then, if a version of the library exists in the deployment environment, applications should include the library in the archive as a bundled optional package so that the bundled library will be selected by the application server instead of the library that has been installed in the extension directory. SummaryWriting portable J2EE applications can be easy when you know the mechanisms available. The J2SE and J2EE platforms define three mechanisms that applications can use to include libraries in a portable way. An application can:
The Java AVK for the Enterprise includes tools that allow users to determine if the application is packaged correctly and is portable. In addition to presenting the mechanisms, this article presented several scenarios for including libraries in applications along with the appropriate mechanism for each scenario. Finally, the article discussed vague areas in the J2EE 1.4 Platform Specification that the application developer needs to be aware of and recommendations for dealing with these areas. For more information, see References. ReferencesThe following resources are recommended for further information on this topic.
| ||||||||||||||||||||||||
|
| ||||||||||||