Application assembly (also known as packaging) is the process of combining discrete components of an application into a single unit that can be deployed to a J2EE-compliant application server. A package can be classified either as a module or as a full-fledged application. This section covers the following topics:
A J2EE module is a collection of one or more J2EE components of the same container type (for example, web or EJB) with deployment descriptors of that type. One descriptor is J2EE standard, the other is Application Server specific. Types of J2EE modules are as follows:
Web Application Archive (WAR): A web application is a collection of servlets, HTML pages, classes, and other resources that can be bundled and deployed to several J2EE application servers. A WAR file can consist of the following items: servlets, JSP files, JSP tag libraries, utility classes, static pages, client-side applets, beans, bean classes, and deployment descriptors (web.xml and optionally sun-web.xml).
EJB JAR File: The EJB JAR file is the standard format for assembling enterprise beans. This file contains the bean classes (home, remote, local, and implementation), all of the utility classes, and the deployment descriptors (ejb-jar.xml and sun-ejb-jar.xml). If the EJB component is an entity bean with container managed persistence, a .dbschema file and a CMP mapping descriptor, sun-cmp-mapping.xml, must be included as well.
Application Client Container JAR File: An ACC client is an Application Server specific type of J2EE client. An ACC client supports the standard J2EE Application Client specifications, and in addition, supports direct access to the Application Server. Its deployment descriptors are application-client.xml and sun-application-client.xml.
Resource RAR File: RAR files apply to J2EE CA connectors. A connector module is like a device driver. It is a portable way of allowing EJB components to access a foreign enterprise system. Each Application Server connector has a J2EE XML file, ra.xml.
Package definitions must be used in the source code of all modules so the class loader can properly locate the classes after the modules have been deployed.
Because the information in a deployment descriptor is declarative, it can be changed without requiring modifications to source code. At run time, the J2EE server reads this information and acts accordingly.
The Application Server also supports lifecycle modules. See Chapter 10, Developing Lifecycle Listeners for more information.
EJB JAR and Web modules can also be deployed separately, outside of any application, as in the following figure. EJB components are assembled in a JAR file with ejb-jar.xml and sun-ejb-jar.xml deployment descriptors. Web components are assembled in a WAR file with web.xml and sun-web.xml deployment descriptors. Both module types are deployed to the Application Server.
A J2EE application is a logical collection of one or more J2EE modules tied together by application deployment descriptors. Components can be assembled at either the module or the application level. Components can also be deployed at either the module or the application level.
The following diagram illustrates how components are assembled into modules and then assembled into an Application Server application and deployed. EJB components are assembled in a JAR file with ejb-jar.xml and sun-ejb-jar.xml deployment descriptors. Web components are assembled in a WAR file with web.xml and sun-web.xml deployment descriptors. An application client is assembled in a JAR file with application-client.xml and sun-application-client.xml deployment descriptors. A resource adapter is assembled in a RAR file with a ra.xml deployment descriptor. All modules are assembled in an EAR file and deployed to the Application Server.
Each module has an Application Server deployment descriptor and a J2EE deployment descriptor. The Application Server uses the deployment descriptors to deploy the application components and to register the resources with the Application Server.
An application consists of one or more modules, an optional Application Server deployment descriptor, and a required J2EE application deployment descriptor. All items are assembled, using the Java ARchive (.jar) file format, into one file with an extension of .ear.
The J2EE platform provides assembly and deployment facilities. These facilities use WAR, JAR, and EAR files as standard packages for components and applications, and XML-based deployment descriptors for customizing parameters.
J2EE standard deployment descriptors are described in the J2EE specification, v1.4. You can find the specification at http://java.sun.com/products/.
To check the correctness of these deployment descriptors prior to deployment, see The Deployment Descriptor Verifier.
The following table shows where to find more information about J2EE standard deployment descriptors.
Table 3–1 J2EE Standard Descriptors
Deployment Descriptor |
Where to Find More Information |
---|---|
Java 2 Platform Enterprise Edition Specification, v1.4, Chapter 8, “Application Assembly and Deployment - J2EE:application XML DTD” |
|
Java Servlet Specification, v2.4 Chapter 13, “Deployment Descriptor,” and JavaServer Pages Specification, v2.0, Chapter 7, “JSP Pages as XML Documents,” and Chapter 5, “Tag Extensions” |
|
Enterprise JavaBeans Specification, v2.1, Chapter 16, “Deployment Descriptor” |
|
Java 2 Platform Enterprise Edition Specification, v1.4, Chapter 9, “Application Clients - J2EE:application-client XML DTD” |
|
Java 2 Enterprise Edition, J2EE Connector Architecture Specification, v1.0, Chapter 10, “Packaging and Deployment.” |
The Application Server uses additional deployment descriptors for configuring features specific to the Application Server. The sun-application.xml, sun-web.xml, and sun-cmp-mappings.xml files are optional; all the others are required.
To check the correctness of these deployment descriptors prior to deployment, see The Deployment Descriptor Verifier.
The following table lists the Application Server deployment descriptors and their DTD files. For complete descriptions of these files, see Appendix A, Deployment Descriptor Files.
Table 3–2 Sun Java System Application Server Descriptors
Deployment Descriptor |
DTD File |
Description |
---|---|---|
Configures an entire J2EE application (EAR file). |
||
Configures a web application (WAR file). |
||
Configures an enterprise bean (EJB JAR file). |
||
Configures container-managed persistence for an enterprise bean. |
||
Configures an Application Client Container (ACC) client (JAR file). |
||
Configures the Application Client Container. |
Names of applications and individually deployed EJB JAR, WAR, and connector RAR modules must be unique within an Application Server domain. Modules of the same type within an application must have unique names. In addition, for entity beans that use CMP,.dbschema file names must be unique within an application.
If you do not explicitly specify a name, the default name is the first portion of the file name (without the .war or .jar extension). Modules of different types can have the same name within an application, because the directories holding the individual modules are named with _jar, _war and _rar suffixes. This is the case when you use the Administration Console, the asadmin command, or the deploytool to deploy an application or module. See Tools for Deployment.
Make sure your package and file names do not contain spaces or characters that are illegal for your operating system.
If you are writing your own JSR 88 client to deploy applications to the Application Server using the following API, the name of the application is taken from the display-name entry in the J2EE standard deployment descriptor, because there is no file name in this case. If the display-name entry is not present, the Application Server creates a temporary file name and uses that name to deploy the application.
javax.enterprise.deploy.spi.DeploymentManager.distribute(Target[], InputStream, InputStream)
Neither the Administration Console, the asadmin command, nor the deploytool uses this API.
For more information about JSR 88, see the JSR 88 page at http://jcp.org/en/jsr/detail?id=88.
When you deploy an application, the application is expanded to an open directory structure, and the directories holding the individual modules are named with _jar, _war and _rar suffixes. If you use the asadmin deploydir command to deploy a directory instead of an EAR file, your directory structure must follow this same convention.
Module and application directory structures follow the structure outlined in the J2EE specification. Here is an example directory structure of a simple application containing a web module, an EJB module, and a client module.
+ converter_1/ |--- converterClient.jar |--+ META-INF/ | |--- MANIFEST.MF | |--- application.xml | |--- sun-application.xml |--+ war-ic_war/ | |--- index.jsp | |--+ META-INF/ | | |--- MANIFEST.MF | |--+ WEB-INF/ | |--- web.xml | |--- sun-web.xml |--+ ejb-jar-ic_jar/ | |--- Converter.class | |--- ConverterBean.class | |--- ConverterHome.class | |--+ META-INF/ | |--- MANIFEST.MF | |--- ejb-jar.xml | |--- sun-ejb-jar.xml |--+ app-client-ic_jar/ |--- ConverterClient.class |--+ META-INF/ |--- MANIFEST.MF |--- application-client.xml |--- sun-application-client.xml |
Here is an example directory structure of an individually deployed connector module.
+ MyConnector/ |--- readme.html |--- ra.jar |--- client.jar |--- win.dll |--- solaris.so |--+ META-INF/ |--- MANIFEST.MF |--- ra.xml |
Whether you deploy an individual module or an application, deployment affects both the file system and the server configuration.
The following figure illustrates the environment for individually deployed module-based deployment.
For file system entries, modules are extracted as follows:
domain-dir/applications/j2ee-modules/module-name domain-dir/generated/ejb/j2ee-modules/module-name domain-dir/generated/jsp/j2ee-modules/module-name
The applications directory contains the directory structures described in Directory Structure. The generated/ejb directory contains the stubs and ties that an ACC client needs to access the module; the generated/jsp directory contains compiled JSP files.
Lifecycle modules (see Chapter 10, Developing Lifecycle Listeners) are extracted as follows:
domain-dir/applications/lifecycle-modules/module-name
Configuration entries are added in the domain.xml file as follows:
<server> <applications> <type-module> ...module configuration... </type-module> </applications> </server>
The type of the module in domain.xml can be lifecycle, ejb, web, or connector. For details about domain.xml, see the Sun Java System Application Server Platform Edition 8.1 2005Q2 Update 2 Administration Reference.
The following figure illustrates the environment for application-based deployment.
For file system entries, applications are extracted as follows:
domain-dir/applications/j2ee-apps/app-name domain-dir/generated/ejb/j2ee-apps/app-name domain-dir/generated/jsp/j2ee-apps/app-name
The applications directory contains the directory structures described in Directory Structure. The generated/ejb directory contains the stubs and ties that an ACC client needs to access the module; the generated/jsp directory contains compiled JSP files.
Configuration entries are added in the domain.xml file as follows:
<server> <applications> <j2ee-application> ...application configuration... </j2ee-application> </applications> </server>
For details about domain.xml, see the Sun Java System Application Server Platform Edition 8.1 2005Q2 Update 2 Administration Reference.
Understanding Application Server classloaders can help you determine where and how you can position supporting JAR and resource files for your modules and applications.
In a Java Virtual Machine (JVM), the classloaders dynamically load a specific Java class file needed for resolving a dependency. For example, when an instance of java.util.Enumeration needs to be created, one of the classloaders loads the relevant class into the environment. This section includes the following topics:
Classloaders in the Application Server runtime follow a hierarchy that is illustrated in the following figure and fully described in Table 3–3.
Note that this is not a Java inheritance hierarchy, but a delegation hierarchy. In the delegation design, a class loader delegates classloading to its parent before attempting to load a class itself. A class loader parent can be either the System Classloader or another custom class loader. If the parent class loader can’t load a class, the findClass() method is called on the class loader subclass. In effect, a class loader is responsible for loading only the classes not available to the parent.
The Servlet specification recommends that the Web Classloader look in the local class loader before delegating to its parent. You can make the Web Classloader follow the delegation model in the Servlet specification by setting delegate="false" in the class-loader element of the sun-web.xml file. It’s safe to do this only for a web module that does not interact with any other modules.
The default value is delegate="true", which causes the Web Classloader to delegate in the same manner as the other classloaders. You must use delegate="true" for a web application that accesses EJB components or that acts as a web service client or endpoint. For details about sun-web.xml, see The sun-web.xml File.
Access to components within applications and modules installed on the server occurs within the context of isolated class loader universes, each of which has its own EJB, Web, and JSP Engine classloaders.
Application Universe: Each J2EE application has its own class loader universe, which loads the classes in all the modules in the application.
Individually Deployed Module Universe: Each individually deployed EJB JAR, web WAR, or lifecycle module has its own class loader universe, which loads the classes in the module.
A resource such as a file that is accessed by a servlet, JSP, or EJB component must be in a directory pointed to by the class loader’s classpath. For example, the web class loader’s classpath includes these directories:
module-name/WEB-INF/classes module-name/WEB-INF/lib
If a servlet accesses a resource, it must be in one of these directories or it is not loaded.
In iPlanet Application Server 6.x, individually deployed modules shared the same class loader. In subsequent Application Server versions, each individually deployed module has its own class loader universe.
Since each application or individually deployed module class loader universe is isolated, an application or module cannot load classes from another application or module. This prevents two similarly named classes in different applications from interfering with each other.
To circumvent this limitation for libraries, utility classes, or individually deployed modules accessed by more than one application, you can include the relevant path to the required classes in one of these ways:
To use the System Classloader, do one of the following, then restart the server:
Use the Administration Console. Select the JVM Settings component under the relevant configuration, select the Path Settings tab, and edit the Classpath Suffix field. For details, see the Sun Java System Application Server Platform Edition 8.1 2005Q2 Update 2 Administration Guide.
Edit the classpath-suffix attribute of the java-config element in the domain.xml file. For details about domain.xml, see the Sun Java System Application Server Platform Edition 8.1 2005Q2 Update 2 Administration Reference.
Using the System Classloader makes an application or module accessible to any other application or module across the domain.
To use the Common Classloader, copy the JAR and ZIP files into the domain-dir/lib directory or copy the .class files into the domain-dir/lib/classes directory, then restart the server.
Using the Common Classloader makes an application or module accessible to any other application or module across the domain.
To use the Java optional package mechanism, copy the JAR and ZIP files into the domain-dir/lib/ext directory, then restart the server.
Using the Java optional package mechanism makes an application or module accessible to any other application or module across the domain.
For example, this is the recommended way of adding JDBC drivers to the Application Server. For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Platform Edition 8.1 2005Q2 Update 2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.
By packaging the client JAR for one application in a second application, you allow an EJB or web component in the second application to call an EJB component in the first (dependent) application, without making either of them accessible to any other application or module.
As an alternative for a production environment, you can have the Common Classloader load client JAR of the dependent application as described in Using the Common Classloader restart the server to make the dependent application accessible, and it is accessible across the domain.
Deploy the dependent application.
Add the dependent application’s client JAR file to the calling application.
For a calling EJB component, add the client JAR file at the same level as the EJB component. Then add a Class-Path entry to the MANIFEST.MF file of the calling EJB component. The Class-Path entry has this syntax:
Class-Path: filepath1.jar filepath2.jar ...
Each filepath is relative to the directory or JAR file containing the MANIFEST.MF file. For details, see the J2EE specification, section 8.1.1.2, “Dependencies.”
For a calling web component, add the client JAR file under the WEB-INF/lib directory.
If you need to package the client JAR with both the EJB and web components, set delegate="true" in the class-loader element of the sun-web.xml file.
This changes the Web Classloader so it follows the standard class loader delegation model and delegates to its parent before attempting to load a class itself.
For most applications, packaging the client JAR file with the calling EJB component is sufficient. You do not need to package the client JAR file with both the EJB and web components unless the web component is directly calling the EJB component in the dependent application.
Deploy the calling application.
The calling EJB or web component must specify in its sun-ejb-jar.xml or sun-web.xml file the JNDI name of the EJB component in the dependent application. Using an ejb-link mapping does not work when the EJB component being called resides in another application.