Section 2.1. J2EE Application Assembly Model


2.1. J2EE Application Assembly Model

First, let's get the J2EE terminology straight. Figure 2-1 depicts the assembly model for J2EE applications. J2EE applications are composed of one or more components. A component is a functional element of an application that runs within a container and makes use of the runtime services provided by the container. These runtime services might be security management services, transaction management services, lifecycle services, or others, depending on the type of component and the type of container. A component consists of one or more Java classes that implement the component, along with any component-specific resources like properties files, images, and the like. J2EE components (and their containers ) come in five flavors: application clients , applets , web, EJB, and resource adapters .[*] Each type of container is capable of providing a specific set of APIs and runtime services to its corresponding components.

[*] It's important to note that most references on this subject distinguish resource adapters as a different category of "component" in the J2EE model: a lower-level component that represents a resource to be used by the other, higher-order components, without a formal container model like the others. But for the sake of consistency of the assembly and deployment model, they are included here among the other J2EE component types, since at a general level, they are handled much the same as the other components.

J2EE components are grouped together and deployed in modules , which are collections of components of the same type, to be run inside the corresponding container type. A module contains all of the component-specific classes, plus any

Figure 2-1. J2EE assembly model (conceptual)


class libraries needed by the components and other cross-component resources, such as datafiles, HTML documents (for web components), and image files. Each module also contains a standard XML deployment descriptor that provides descriptive information, external resource references, and configuration details about each component it contains. If required, a module can also contain application server-specific details, such as configuration files, classes, and resources that are required by a particular application server. Most application servers, for example, allow you to specify additional configuration parameters, not included in the standard J2EE deployment descriptors , in separate configuration files. The application server vendor dictates the format for these files and where they should be included in the module archive. Modules are packaged in the form of jar files, with the deployment descriptor, classes, class libraries, and other resources placed in specific locations in the jar file.

An enterprise application archive, or ear file, is a set of one or more modules, and these modules collectively contain all of the components of an application. An application archive also contains a deployment descriptor, which specifies the modules that it contains and several other application-wide configuration details. Like components, application archives are packaged into jar files with a particular layout, containing the deployment descriptor for the application, the module jar files, and any other application resources, such as documentation for the application.

In the remainder of this section, we'll talk about the general steps and concepts involved in assembling and deploying J2EE applications. Following this, we'll discuss component modules and application assemblies in more detail, using an example application as a guide.

2.1.1. Assembling Applications

As discussed in the introduction to this chapter, we've intentionally made the distinction between assembling and deploying applications because they really are two distinct stages in getting a J2EE application up and running. Assembling an application involves getting all of the elements of the application together in the right package structure and with the right configuration information included. Deploying an application is the act of taking the application assembly and plugging it into the application server environment so that it can actually run.

The first step in assembling an application is to assemble the component modules that make up the application. Once this is accomplished, you package up the component modules into an application archive.

An application is fully assembled once all of its component modules have been pulled together into an application archive, as shown in Figure 2-2. In the example shown, the application archive contains two component modules, a web module and an EJB module. Each component module contains a deployment descriptor describing the components themselves, how they should be managed by the container at runtime, and references to any resources or other components that the module's components require in order to operate correctly.

The application assembly itself also includes an application.xml deployment descriptor, which references all of the modules that make up the application.

At this point, the application is assembled but not deployed. All of the resource references in the component module descriptors are dangling, unresolvedwe can't assign actual resources to these references until we put the application into a physical server environment. It is possible to resolve some internal component references at this point, if they reside in the same application assembly. For example, if one of the component modules in Figure 2-2 references an EJB component and that EJB component is contained in the other component module, we can specify that internal reference directly in the deployment descriptor of the referring component. But for other resources, like JDBC DataSources and JavaMail Sessions, we won't be able to connect the deployment descriptor references to actual resources until we know the application server into which we're deploying and how its resources are configured internally.

This separation of assembly and deployment of components and applications, using deployment descriptors as the mediator between these two stages, helps you

Figure 2-2. Assembled application archive


to develop enterprise applications that migrate easily across environments. You may be writing a shopping cart application, for example, with an EJB component that requires a database connection in order to store and update order items. You might be developing this application in a development environment using a MySQL database but need to run it in a production environment using an Oracle database. The database requirement can be specified clearly as a reference to a DataSource in the EJB deployment descriptor when the application is assembled. When the application is deployed to the development environment, the DataSource reference can be bound to a DataSource configured against the MySQL database. When the application is eventually deployed to production, the same application assembly can be used, but the resource reference will now be bound to a DataSource configured to connect to the production Oracle database.

2.1.2. JNDI Configuration Services

Given all this, the configuration services provided by an application server are a critical element in deploying J2EE applications. Various runtime assets required by your components, such as database connections, JMS message queues, JCA resource adapters, or even other J2EE components, will be provided by the application server at runtime. These assets will be located at runtime using JNDI lookups, so it's critical that all of the assets referenced in the component deployment descriptors are configured properly in the JNDI namespace of the application server.

More complete details on JNDI and its use with general directory services can be found in Chapter 9. Here, we'll discuss the naming conventions typically used for different resources and components published in an application server's JNDI service and how names used in module deployment descriptors are resolved against the real names of these resources and components.

2.1.2.1. Naming conventions

J2EE specifies some basic naming conventions for the assets published in the server's JNDI service for application components. In general, runtime assets are given names within the java:comp/env namespace in the JNDI service. The java:comp portion of the namespace indicates that the assets are targeted for J2EE components, and the /env branch indicates assets that are part of the component runtime environment. Some application-wide assets, such as CORBA ORBs, are stored directly in the java:comp namespace. Table 2-1 shows the various assets that can be stored in a JNDI service on behalf of J2EE components and the conventional namespace that is used for the names of these assets.

Table 2-1. JNDI naming conventions for J2EE runtime assets

Asset category

Java types supported

JNDI name/namespace

Database connections

javax.sql.DataSource

java:comp/env/jdbc/*

General messaging connections and destinations

javax.jms.Queue

javax.jms.QueueConnectionFactory

javax.jms.Topic

javax.jms.TopicConnectionFactory

java:comp/env/jms/*

Email messaging connections

javax.mail.Session

java:comp/env/mail/*

HTTP URL connections

java.net.URL

java:comp/env/url/*

Transactions

javax.transaction.UserTransaction

java:comp/UserTransaction

CORBA object request broker

org.omg.CORBA.ORB

java:comp/ORB

Resource adapter connections

javax.resource.cci.ConnectionFactory

java:comp/env/eis/*

EJB components

javax.ejb.EJBHome

javax.ejb.EJBLocalHome

java:comp/env/ejb/*

General environment entries

Java basic data types (Boolean, Byte, Character, Double, Float, Integer, Long, Short, String)

java:comp/env/*


These naming conventions require coordination among the component code, the deployment descriptors, and the application server. In the component source code, you perform JNDI lookups to access runtime assets. You might access a JDBC DataSource from a component like this:

 Context context = new InitialContext(  ); DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/myDS");

We're assuming here that a DataSource is available under the name myDS within the standard J2EE namespace for JDBC resources, java:comp/env/jdbc.

The deployment descriptor for the component making the JNDI reference must declare its dependence on this JNDI asset. Assuming that this code resides in the implementation code for an entity EJB component, the EJB deployment descriptor would also need to include a segment declaring the dependence of the component on the DataSource, like this:

 . . . <resource-ref>     <res-ref-name>jdbc/myDS</res-ref-name>     <res-type>javax.sql.DataSource</res-type>     <res-auth>Container</res-auth> </resource-ref> . . .

This entry declares that the component looks for a javax.sql.DataSource under the name jdbc/myDS within the standard J2EE namespace, java:comp/env. The standard namespace prefix is not included in the deployment descriptor declaration; it's assumed for all asset declarations. The application server is responsible for creating the default java:comp/env namespace in its internal JNDI namespace.

2.1.2.2. Two-level name resolution

Many application servers support two-level name bindings for the linking of JNDI names to actual assets. This capability offers flexibility and, in some cases, efficiency when operating a number of components and applications in the same server.

Two-level name binding allows you to assign an independent name to an asset when configuring it within the application server and then link this asset name to the name specified in the component deployment descriptors. Suppose, for example, that a deployment descriptor declares a requirement for a JavaMail Session to be deployed on the server under the name java:comp/env/mail/AppSession. If the application server supports two-level name bindings, we can configure a Session on the server under an independent name, such as java:comp/mail/GenericSession, and link the asset name to the name required by the component module. In effect, this linking ensures that the runtime JNDI lookup at java:comp/env/mail/AppSession actually resolves to the Session deployed under java:comp/mail/GenericSession. The mechanics of making this linkage is application-dependentit can be done in a server-specific configuration file, in a web administration tool, or in something else entirely. Later in this chapter, we'll see a concrete example of configuring an asset this way in JBoss.

Not only does this two-level binding feature allow you to manage your namespace more flexibly, but it can also make it possible to share assets among components and applications running in the same server. Following on to the Session example we just used, suppose this Session were configured with fairly generic settings and that other components also needed a Session configured similarly. We can reuse the same Session asset with other components by simply linking the names that these other components declare for the asset with the same Session that is deployed at java:comp/mail/GenericSession.

2.1.3. Deploying Applications

Deploying an application involves several steps, including resolving resource and component references , managing the classloader used by the application server or servers, and finally, physically deploying the application. We describe this process next.

2.1.3.1. Resolving resource and component references

Once we move our application assembly into an application server environment (i.e., deploy our application), we need to settle all of the resource and component references contained in the various deployment descriptors. In the J2EE model, application servers make resources available to applications through an internal directory, accessed at runtime using the Java Naming and Directory Interface (JNDI). This internal directory could be a full LDAP server, a CORBA Naming Service, or any other directory service supported by JNDI.

Figure 2-3 shows the situation after a J2EE application assembly has been successfully deployed to an application server environment. The resource and component references in the module descriptors have been linked to deployed resources and components in the application server. These references are linked through the application server's JNDI service: components and resources have been deployed in the application server and "published" in its JNDI service under specific names. These components and resources are then linked to the references in the deployment descriptors in our deployed application, and the application is fully deployed.

If a component reference in a deployment descriptor needs to be linked to a component residing in the same application assembly, it's possible to make that link directly in the module deployment descriptor, and not through the server's JNDI service. This is depicted in Figure 2-3 by the "internal reference" link between the two modules in the application. Otherwise, the resource and component references need to be resolved to real assets through the application server's JNDI service.

2.1.3.2. Runtime classloading models

Another key consideration when deploying applications is the classloading model used by the application server. Typically, a J2EE application server runs within a parent Java virtual machine, and that parent JVM may spawn other JVMs or non-Java processes to run specific runtime elements (messaging services, directory services, etc.). Within the application server's JVM, the management of classloaders can be done in a variety of ways. The most simplistic approach would be to have all applications share the same classloader. In a multiple application scenario, this is usually not desirable since various applications, or even different versions of the same application, may depend on different versions of Java

Figure 2-3. Deployed application


libraries and classes, which would cause conflicts in a single-classloader situation (the first version of a class loaded at runtime would be used by all applications in the server). If an application server runs all applications within the same classloader, then you may find yourself forced to run multiple server instances in order to run each application with the proper versions of libraries and classes.

A more realistic runtime model would be to assign a separate classloader to each deployed application. This allows each application to load its own versions of specific classes, independent of other applications. Assuming that the server is using the standard Java classloader implementation, each application classloader would be a child of the server's main classloader, so any libraries that you truly want to share across all applications (i.e., the same version used by all applications) will be loaded by the main server at startup. This is typically done by either adjusting the server's startup classpath or putting the shared libraries in a special library directory.

Some application servers impose a single classloading scheme on deployed applications, while others allow you to configure the classloading scheme at a server or an application level. It's important to understand the classloading schemes supported by your application server and to adjust these settings if needed.

2.1.3.3. Physical deployment

The physical steps that you take to deploy an application in an application server are a vendor-specific detail. The resource and component references might be resolved using server-specific configuration files, as depicted in Figure 2-3, or an application server may provide a web-based administration tool that allows you to graphically link references in deployment descriptors to actual resources and components running in the application server. The documentation for your application server should explain the details.

Now that we've seen the J2EE assembly and deployment model at a conceptual level, let's run through the technical details, starting with the creation of component modules, then application assemblies, and then deployment. Along the way, we'll work with a concrete example application consisting of web and EJB components.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net