Class Loader and Java /J2EE Application Packaging

Just a step forward to discuss about java and j2EE class loader and Java/J2EE application packaging. Mainly on the complex J2EE application packaging.

Tuesday, December 19, 2006

Packaging J2EE Application

Most of the IDEs provide tools or wizards for packaging J2EE application. Packaging a J2EE application application using these tools or wizards are straightforward and simple as the tool takes care of the packaging. Most of the time the developers don't bother to look at the underlying scripts (like ant script) which takes care of the packaging. When it comes to package the application for optimization or to maintain proper dependency between application modules without redundancy copy of modules then it becomes necessary to play around the underlying scripts of the IDE or tools that takes care of the packaging or it may be required to do the packaging by writing your own scripts.( For example ant script or shell scripts) The different scenarios of J2EE application may need different approaches for packaging. For example
  1. Application with stand alone web modules without any interdependency. No sharing of libraries between web modules(also EJB modules). Each module has it's own library copy.
  2. Application with more than one modules(multiple web and multiple EJB modules) and the application want to share the same library JAR file among all the modules rather than bundle duplicate copies of library in each module.
  3. Multiple applications need to share the same library JAR file among the applications not just among modules.
  4. The J2EE application may expect a library to be made available by the server and want to use that library instead of having it's own library included on the ear file(For example a Logging library).

The below given approaches addresses addresses some of the common scenarios that a J2EE developer may face during an application development and a recommended packaging structure for the same.

Approach 1 : No sharing of Libraries between modules

This is the most simplest approach for packaging a J2EE application. In this case the developers may not need to touch the underlying scripts of IDE tools. In this case one module has all the libraries that it needs. That is to package all the required jar files for the EJB jar file under the root of the jar file and in case of web application add all the utility and library classes under the WEB-INF\lib folder.

Let us take the following example: Let the J2EE application has following modules.

  1. One EJB Module (Let it be ejb1.jar )
  2. One EJB Client Module (Let it be ejb1_client.jar )
  3. Two Web Module which depends on the ejb client classes( Let it be web1.war)
  4. One Utility jar file containing all the utility classes (Let it be util.jar)

If the above modules are packaged in the above approach to create a J2EE ear file let it be app1.ear, then the app1.ear structure will look like the below given diagram.(To keep the diagram simple only the files that affects the packaging method are shown )

    app1.ear
        META_INF/application.xml
        ejb.jar
            META-INF/ejb-jar.xml
            ejb1_client.jar
            util.jar
        web1.war
            WEB-INF/web.xml
            WEB-INF/lib/ejb1_client.jar
            WEB-INF/lib/util.jar
        web2.war
            WEB-INF/web.xml
            WEB-INF/lib/ejb1_client.jar
            WEB-INF/lib/util.jar

The files shown in blue color are duplicated on each module to make sure the module has all the necessary library that it needs.

Approach 2 : Multiple modules in the same application sharing the library

This approach is better than the above approach in some scenarios as this removes the duplicate copy of library files while still maintaining the portability of the application. In this approach all the libraries are withing the .ear file, but instead of having duplicated copy of library files the modules keep a reference to the single shared library that is within the .ear file. Details are described below.

As per the J2EE 1.4 specification a JAR format file (such as a .jar file, .war file, or .rar file) can reference a .jar file by naming the referenced .jar file in the Class-Path header entry of the referencing JAR file’s manifest file. The referenced .jar file is referred using a URL relative to the URL of the referencing JAR file. The Manifest file is named META-INF/MANIFEST.MF in the JAR file. The Class-Path entry in the Manifest file is of the form

Class-Path: list-of-jar-files-separated-by-spaces

Now let us consider the above example and package the application using the jar file reference concept as specified in J2EE 1.4 specification.

The application ear file structure will look like the below given diagram.

    app2.ear
        META_INF/application.xml
        ejb1_client.jar
        utl.jar
        ejb.jar       Class-Path: ejb1_client.jat util.jar
             META-INF/ejb-jar.xml
        web1.war   Class-Path: ejb1_client.jat util.jar
            WEB-INF/web.xml
        web2.war   Class-Path: ejb1_client.jat util.jar
            WEB-INF/web.xml

As given in above the EAR file structure, the common libraries or packages are kept on the root of the application ear file and references to these files are given in each modules ( jar / war files). The Class-path entry of each META-INF/MANIFEST.MF file is shown in green color.

Approach 3 : Multiple applications sharing the same library.

In some cases different applications on the same application server uses the same library. For example the logging mechanism or the JDBC driver .If an organization uses oracle database through out the enterprise then all the application developer can expect the oracle driver to be made available to the application by the application server, instead of each application having a duplicate copy of the JDBC library. This approach may also help in replacing the common library for all application without replacing one by one for each application. Such libraries are often called installed libraries. As per J2EE 1.4 specification this can be done by adding the reference to the external libraries by the 'Extension-List' attribute in the manifest file to reference one or more library JAR files that are not bundled in the EAR file but are installed in some well-known location, usually the lib/ext directory of the Java Runtime Environment (JRE). In this approach, the library JAR files are not included as part of the EAR file but the extension list include their reference. Any library JAR file referenced is external to the EAR file must be installed in the lib/ext directory, and should be made available by the application server.

In the application EAR file, the Extension-List attribute of the manifest file is used to express the dependency of the EAR file on a library JAR file. More than one library can be listed in the Extension-List. The applications will not deploy if the application server cannot find the library and resolve the dependency.

Let us take the above example repackage the application expecting the util.jar library to be present as a installed library in the target application server. In this case the package will look like the below given diagram.

    app3.ear
        META_INF/application.xml
        ejb1_client.jar
 ejb.jar  
     META-INF/MANIFEST.MF
                Class-Path: ejb1_client.jar
                Extension-List.util
                Util-Extension-Name: com/example/util
                Util-Extension-Specification-Version: 1.0
        web1.war :
            META-INF/MANIFEST.MF
                Class-Path: ejb1_client.jar
                Extension-List.util
                Util-Extension-Name: com/example/util
                Util-Extension-Specification-Version: 1.0
            WEB-INF/web.xml
        web2.war
            META-INF/MANIFEST.MF
                Class-Path: ejb1_client.jar
                Extension-List.util
                Util-Extension-Name: com/example/util
                Util-Extension-Specification-Version: 1.0
            WEB-INF/web.xml

For an .ear file to work with external optional package reference the referred jar library should have proper header information in the MANIFEST.MF file. For the above example the util.jar file should have following information in the MANIFEST.MF file to make sure the ear file gets loaded properly.

Extension-Name: com/example/util
Specification-Title: example.com’s util package
Specification-Version: 1.0
Specification-Vendor: example.com

J2EE specification gives the what is expected from an application server and leaves the implementation details to the vendors. Different vendors implemens the specification in their own ways and also gives some additional vendor specific features for tunning the application. Some of them will be discusses in comming blogs.

1 Comments:

  • At 9:14 AM, Blogger Pradeep Kumar Sahu said…

    Here is a good link to know about Oracle AS class loading.
    http://www.oracle.com/technology/tech/java/oc4j/pdf/ClassLoadingInOC4J_WP.pdf

     

Post a Comment

<< Home