Configuring Web Applications


The Java servlet specification describes a generic configuration of a Web application that allows the Web application to be portable across containers through the use of the web.xml file. This means a packaged WAR file would theoretically be able to be deployed on nearly any application server or Web container without any need to change the configuration or code. However, each application server typically has additional options that can enhance the power of the application through the use of a proprietary configuration file.

Nearly every application server and Web container has a descriptor file that enables you to extend the capabilities and configuration beyond the specification. For example, in standalone Tomcat, the extended configuration is found in the context.xml file; in BEA Weblogic, it is found in the weblogic.xml file; and in standalone Jetty, it is the web-jetty.xml file. Geronimo also allows you to extend the capabilities of your Web application with the geronimo-web.xml file.

Geronimo-Specific Web App Deployment Plan

The geronimo-web.xml file is essentially a plan file that describes the Web application attributes and provides the ability to configure additional GBeans, allowing you to set Geronimo-specific properties to alter the characteristics of the Web application. In this file, you can set generic Web properties, such as the context root, the priority class loader, and set resource and naming references, as well as setup security, JNDI naming, and so on. It also allows you to set container-specific properties that are very specific to the Tomcat or Jetty containers. For example, you would be able to declare such configurations as a Tomcat realm and valve chain, and specify which virtual host the Web application should belong to for which Tomcat’s container would only understand. This file is optional when deploying a WAR file and is only needed if you must set specific properties for the application. However, it is strongly recommended that all Web applications use this file.

The geronimo-web.xml is known as the Web app deployment plan file. It is structured within <web-app> elements and can use the contents of this plan in one of three ways:

  • The geronimo-web.xml file can be included in the WAR file’s /WEB-INF directory and packaged with the WAR. The Geronimo Web builder will find the file upon deployment and process its contents at deploy time.

  • The geronimo-web.xml file can be deployed along with the module binaries, using the command-line deployer. In this case, the deployment plan can be maintained external to binaries of the application.

  • The <web-app> can be embedded in another plan file, such as a geronimo-application.xml file that is part of an EAR.

Which of the options you choose is largely dependent upon how you wish to package and deploy the application. There are positives and negatives to whether you choose to keep your Web descriptor in a geronimo-web.xml and have it part of your archive, or deploy the plan externally. Embedding it in your archive keeps everything together as a single file, and deployment becomes simple because there is no external plan to tell the deployer about. The negative side of this is that if you must change the plan for any reason, you need to unpack/rebuild your archive to embed a new plan file.

Deploying/Undeploying/Starting/Stopping Applications

Deploying Web applications can be performed in several different ways. You can use the command-line deployer script (deploy.sh or deploy.bat) in the bin directory, or type in the full Java command. The following example uses the command-line deployer script and uses an external plan file that contains the <web-app> descriptor. Note that a plan deployed in this way does not have to be named geronimo-web.xml; it can have any name.

 deployer deploy myapp.war external-plan.xml

If your Geronimo-specific plan is embedded, it must be named geronimo-web.xml and it must be placed into your WAR file’s WEB-INF directory; otherwise, the Geronimo server will not find it during deployment. For embedded plans in a WAR file, you may deploy it without declaring an external plan as follows:

 deployer deploy myapp.war

To undeploy an application using the command-line interface, use the undeploy command, along with the named moduleId of your application. For example, if you have an application with the moduleId set to wrox/MyApp/1.0/car, you would undeploy it with the following:

 deployer undeploy wrox/MyApp/1.0/car

Starting and stopping an already deployed application can be handled by using the start and stop commands, along with the named moduleId of your application.

You may also use the console to deploy your applications. The left-side navigation menu of the Web console has a Deploy New link under the Applications heading that will show the Install New Applications portlet, as shown in Figure 10-5.

image from book
Figure 10-5: Install New Applications portlet of the Web console

This portlet allows you to choose your WAR file, as well as your plan file if you wish you have an external plan to deploy with. You may start and stop your Web applications with the Web App WARs navigation link on the left side of the Web console under the Applications heading. As shown in Figure 10-6, this link will show the Installed Web Applications portlet. From this portlet, you can see the state of your Web applications, and you can stop and start your applications from this screen.

image from book
Figure 10-6: Installed Web Applications portlet of the Web console

Finally, you may also deploy/undeploy your application by copying it into the deploy directory. This is the hot deploy directory and will deploy/undeploy your applications by copying in or removing them from this directory.

Important

Using the deploy directory is only advised for use during development and testing. In a production environment, you should deploy your applications with the command-line interface or the console. The hot deploy does not allow for external plan files.

Web Descriptor Namespace Versions

The geronimo-web.xml plan comes in one of three different versions: Generic, Tomcat, and Jetty. The version you choose will depend on your deployment goals. Depending on the Web container you are using, you will likely want to choose the Jetty or Tomcat version.

If you wanted your application to be able to remain neutral and be deployed to both Tomcat and Jetty, you could use the generic version. Figure 10-7 shows a comparison of the versions.

image from book
Figure 10-7: geronimo-web XML Schemas (XSD) for Generic, Jetty, and Tomcat

The Web descriptor version that is used is determined by the default namespace that is declared in the <web-app> element. For example, to declare a plan that is specific to Jetty, the <web-app> element would be declared as follows:

 <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.1" />

This declaration will have two consequences. First, it will allow Jetty-specific declarations in the plan, and second, when the plan and application are deployed, it will only be deployed to the Jetty container. Therefore, in a situation where Geronimo was running two containers, Tomcat would not deploy the application declared with a Jetty namespace. Table 10-1 lists the different namespaces that are used when requiring a Web application deployment descriptor to use a specific type.

Table 10-1: <web-app> Namespaces and Their Versions
Open table as spreadsheet

Type

Namespace

Generic

xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/web-1.1"

Tomcat

xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.1"

Jetty

xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.1"

Each of the Web application descriptors is generally the same, except that they allow container-specific configuration elements that are only understood by the targeted container.

Table 10-1 lists the three Web application descriptor schemas and the XML namespace that you set to default to enable their use.

The generic descriptor does not have any of the proprietary container declarations that the Tomcat and Jetty versions have, but has a special element named <container-config> that allows you to encapsulate container-specific elements by namespace.

In Listing 10-3, a generic descriptor is shown using both Tomcat and Jetty configurations inside the <container-config> element. Notice that the <tomcat> and <jetty> elements reference a configuration namespace for their respective containers. This is not the same namespace as listed in Table 10-1. These reference only the specific container-only attributes that the other descriptors use. Table 10-2 lists these namespaces.

Listing 10-3: Example Generic geronimo-web.xml Descriptor with Tomcat- and Jetty-Specific Attributes

image from book
 <?xml version="1.0" encoding="UTF-8"?> <web-app   xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1"     xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1"     xmlns:security="http://geronimo.apache.org/xml/ns/security-1.1"     xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1">    <sys:environment>          <sys:moduleId>wrox/exampleapp/1.0/car</sys:moduleId>          <sys:dependencies>              <sys:dependency>                <sys:moduleId>geronimo/j2ee-server/1.1/car</sys:moduleId>              </sys:dependency>            </sys:dependencies>       </sys:environment>     <!-- Web Parameters -->     <context-root>/foobar</context-root>     <context-priority-classloader>false</context-priority-classloader>     <!-- Container specific configuration -->     <container-config>       <!-- Tomcat Specific Container Declarations -->       <tomcat xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.0/config">         <valve-chain>FirstValve</valve-chain>         <host>www.example.com</host>         <cross-context/>       </tomcat>       <!-- Jetty Specific Container Declarations -->       <jetty xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.0/config">         <virtual-host>www.example.com</virtual-host>       </jetty>     </container-config>     <!-  Naming/Ref declarations -->      <naming:resource-env-ref>       <naming:ref-name>jms/LogQueue</naming:ref-name>       <naming:message-destination-link>LoggingQueue</naming:message-destination-link>     </naming:resource-env-ref>     <!-  Security declaration -->     <security-realm-name>geronimo-properties-realm</security-realm-name>     <security>       <default-principal>         <principal                        name="system"/>       </default-principal>       <role-mappings>         <role role-name="admin">           <principal                       name="admin"            designated-run-as="true"/>         </role>       </role-mappings>     </security>     <!-GBean declarations -->     <gbean name="FirstValve"         >       <attribute name="className">          org.apache.catalina.authenticator.SingleSignOn</attribute>     </gbean> </web-app>
image from book

Table 10-2: Container Configuration Namespaces
Open table as spreadsheet

Type

Namespace

Tomcat

xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.0/config"

Jetty

xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.0/config"

In Table 10-2, note that the version of these container configuration XSDs remains at 1.0, even with the Geronimo 1.1 release.

Common Elements

The generic, Tomcat, and Jetty Web descriptors all have a set of elements that are common among all three files (see Table 10-3). Since the Web application descriptors are basically plan files, they allow you to declare dependencies, GBeans, set naming parameters, and declare security mappings and a security realm, just as you would be able to in many other plans.

Table 10-3: Common Elements
Open table as spreadsheet

Element

Description

<web-container>

References a Web container GBean. This feature allows you to run two Web containers at the same time and tells the Web application to which container to deploy the application. If this is omitted, the Web application will use the default Web container to deploy the application.

<context-root>

The context to which the application will be installed. Typically, it will represent the portion of the URL that represents the application. For example, if you wished your URL to be http://yourserver.com:8080/foobar, the value of this element would be /foobar. Note that if this Web application is part of an EAR file, and the EAR contains an application.xml file with a <context-root> declaration, that one will take precedence over the Web version.

<security-realm-name>

References a known security realm typically declared as a GenericSecurityRealm GBean. This would normally be used in conjunction with a login module. See Chapter 15 for configuration.

<security>...</security> block

Provides for declaring role mapping and default principals. See Chapter 15 for configuration.

<naming:xxx>...</naming:xxx> block

Naming block to allow for referencing EJB, JMS, message destinations, and other references. See Chapter 12 for more information.

Container Specific Elements

The generic descriptor is available so that you can create a single deployable plan that can hold container-specific information. It only has one element that is not available in the other descriptors and is the <container-config> element. As explained previously, this element allows you to declare a block based on a namespace that can contain container-specific values. As of this writing, only the configurations that should be referenced are those that are listed in Table 10-2. Keep in mind that the namespaces listed in Table 10-2 are simply subsets of the Jetty and Tomcat web-app descriptor. They only contain the container-specific entries. Following is an example declaration using a Tomcat and Jetty declaration:

 ... <container-config>     <tomcat xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.0/config">     ...     </tomcat>     <jetty xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.0/config">     ...     </jetty> </container-config> ...

It is not mandatory to have both the <jetty> and <tomcat> blocks. You may use both, one, or none. In fact, if your Web application does not need a Tomcat- or Jetty-specific configuration, the <container-config> element may be left out entirely.

Hiding Classes

Although the class loading group elements were covered in Chapter 12, the <hidden-classes> element needs specific mention here because this will likely become an important part, and be used with your Web descriptor plans.

Geronimo is a server that leverages a lot of Open Source projects to produce a best-in-breed application server. This means it probably will be using a lot of the same libraries that you may be using in your applications (such as Spring or ANTLR). When using different versions of the same libraries issues may arise because of the spec for J2EE class loading. You may find that when you deploy a Web application that has Spring or Hibernate as a dependency, you may get a NoClassDefFound or ClassNotFound exception. This issue has to do with the interactions between the Web class loader and server class loader when accessing the used class.

Geronimo uses ANTLR and it’s a part of the parent class loader. When your applications use Hibernate, which uses ANTLR, you may be packaging ANTLR with your WAR. When your application runs, the class loaders check to see if ANTLR is already loaded, and the answer is yes, because it’s already loaded at the server level. But then, according to the spec, there is supposed to be a degree of isolation between the Web application context and the server context (except for certain spec java.* and javax.* classes-see the Child Delegation Model or more information). However, this is only a recommendation and not a strict rule. There are advantages and disadvantages to this model, so to make it a hardened rule could be limiting.

Therefore, it is not necessary for the server to load the child first (again, except in certain circumstances). So the result is a hybrid of a Child Delegation Model and a Parent Delegation Model competing for control with different visibility. In the real world, this means ANTLR is loaded into the server class loader and the Web instantiation has access to the other libraries. When the Web class loader is asked for something, it will say “Have I loaded this class already?” The unequivocal answer is yes. So, it pulls the class from the parent. However, because of the J2EE spec, the server cannot see the Web app’s resources. So, now, when you ask to use ANTLR, you may be using a different version than the one packaged with your application, and the NoClassDefFound or ClassNotFound exceptions may be thrown.

This is actually a common problem with application servers, and the more widely used a library is, the greater the chance that you may run into this problem. One of the most common problems found in several application servers is the Apache Commons Logging API. This is used by many application servers, and yet, developers will include the Commons Logging JAR and end up receiving many different kinds of exceptions. Some application servers will require you to edit the application classpath to get around these issues, so that there are priorities for what libraries are loaded how and when. Keep in mind, the more popular a particular library is, the greater the chance you will run into this problem with it.

The great news is that Geronimo allows you to do something that few other application servers allow. It allows you to declaratively tell the classloader model to hide certain libraries, thus forcing it to use specific versions. This is even more important when your application uses different versions of JARs than the server. This is a great way to get classloading right, without having to experiment with classpaths for hours or days (and even that may not get you anywhere). Geronimo includes the ability to hide the server classes and force the Web loaders to use their own.

You can do this with the <hidden-classes> element in the <environment> section.

For example, if you had a very common Spring/Hibernate application that you wanted to use in Geronimo, you would find that it clashed with the versions of the Spring and ANTLR libraries that are a part of the Geronimo server. To tell Geronimo to have the classloaders use the versions that you include, use a plan that looks like the following:

 <web-app        xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1"        config>      <environment>          <moduleId>wrox/exampleapp/1.0/car</moduleId>          <dependencies>              <dependency>                <moduleId>geronimo/j2ee-server/1.1/car</moduleId>              </dependency>           <dependencies>          <hidden-classes>              <filter>antlr</filter>          </hidden-classes>      <environment>     <context-root>/</context-root> </web-app>

In this plan file, you are telling the Web classloader that any packages that start with antlr should not be pulled by the server and it should only see the Web app’s version. This is an elegant solution to a common problem that has been affecting application servers for some time. This gives you a lot of control over the classloaders in a declarative fashion.

One point to take note of is that Geronimo can also do the opposite. You can use the <non-overridable-classes> element to ensure that the server’s version is used and not the Web app’s local copy. Its syntax is the same as the <hidden-classes> element.

Jetty-Specific Elements in geronimo-web.xml

The Jetty-specific elements may be declared as a child to the <web-app> element if it’s used in conjunction with a Jetty descriptor namespace, or as a child of the <container-config><jetty xmlns="..."> block in a generic descriptor. Jetty contains three container-specific elements: <host>, <virtual-host>, and <session-manager>.

<host>

Normally, the connectors will define which host the application will respond to. You may have set up multiple connectors that listen on different IP addresses. Jetty allows you make the applications more fine-grained in responding to requests at a server/host or IP level. By using the <host> element, you may define which real hosts (not virtual hosts) the Web context will respond to. For example, if you wanted your Web application to respond to localhost and 10.0.0.1, then you would add the following configuration to your Web descriptor:

 ... <host>localhost</host> <host>10.0.0.1</host> ...

There is no limit to the number of hosts that you can add to your application.

<virtual-host>

Jetty allows you to declare which DNS names the Web context will respond to. For example, if you wanted your Web application to respond to www.example.com and www.example.net, then you would add the following configuration to your Web descriptor:

 ... <virtual-host>www.example.com</virtual-host> <virtual-host>www.example.net</virtual-host> ...

This is slightly different from the <host> element as shown before. The difference is a virtual-host may represent the same IP address or single host, but you may make the Web application’s response more fine-grained by stating that it will only answer by certain DNS-resolvable names.

There is no limit to the number of virtual hosts that you can add to your application.

<session-manager>

The <session-manager> element allows you to swap out Jetty’s default SessionManager object. This would be used for clustering or creating your own class that handles session management. A possible use is serializing your session objects to a database or flat file. This element will take a fully qualified class name that implements Jetty’s SessionManager interface.




Professional Apache Geronimo
Professional Apache Geronimo (Wrox Professional Guides)
ISBN: 0471785431
EAN: 2147483647
Year: 2004
Pages: 148

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