TOTD #91: Applying Java EE 6 "web-fragment.xml" to Apache Wicket - Deploy on GlassFish v3


"Extensibility" is a major theme of Java EE 6. This theme enables seamless pluggability of other popular Web frameworks with Java EE 6.

Before Java EE 6, these frameworks have to rely upon registering servlet listeners/filters in "web.xml" or some other similar mechanism to register the framework with the Web container. Thus your application and framework deployment descriptors are mixed together. As an application developer you need to figure out the magical descriptors of the framework that will make this registration.

What if you are using multiple frameworks ? Then "web.xml" need to have multiple of those listeners/servlets. So your deployment descriptor becomes daunting and maintenance nightmare even before any application deployment artifacts are added.

Instead you should focus on your application descriptors and let the framework developer provide the descriptors along with their jar file so that the registration is indeed magical.

For that, the Servlet 3.0 specification introduces "web module deployment descriptor fragment" (aka "web-fragment.xml"). The spec defines it as:

A web fragment is a logical partitioning of the web app in such a way that the frameworks being used within the web app can define all the artifacts without asking devlopers to edit or add information in the web.xml.

Basically, the framework configuration deployment descriptor can now be defined in "META-INF/web-fragment.xml" in the JAR file of the framework. The Web container picks up and use the configuration for registering the framework. The spec clearly defines the rules around ordering, duplicates and other complexities.

TOTD #86 explained how to get started with Apache Wicket on GlassFish. This Tip Of The Day (TOTD) explains how to leverage "web-fragment.xml" to deploy a Wicket application on GlassFish v3. The basic concepts are also discussed here.

For the "Hello World" app discussed in TOTD #86, the generated "web.xml" looks like:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

        <display-name>helloworld</display-name>

         <!-- 
              There are three means to configure Wickets configuration mode and they are
              tested in the order given.
              1) A system property: -Dwicket.configuration
              2) servlet specific <init-param>
              3) context specific <context-param>
              The value might be either "development" (reloading when templates change)
              or "deployment". If no configuration is found, "development" is the default.
        -->

        <filter>
                <filter-name>wicket.helloworld</filter-name>
                <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
                <init-param>
                        <param-name>applicationClassName</param-name>
                        <param-value>org.glassfish.samples.WicketApplication</param-value>
                </init-param>
        </filter>

 <filter-mapping>
  <filter-name>wicket.helloworld</filter-name>
        <url-pattern>/\*</url-pattern>
 </filter-mapping>


</web-app>

This deployment descriptor defines a Servlet Filter (wicket.helloworld) that registers the Wicket framework with the Web container. The filter specifies an initialization parameter that specifies the class name of the Wicket application to be loaded. And it also contains some other information that is also relevant to the framework. None of this application is either required or specified by the application. And so that makes this fragment a suitable candidate for "web-fragment.xml".

Here are the simple steps to make this change:
  1. Remove "src/main/webapp/WEB-INF/web.xml" because no application specific deployment descriptors are required.
  2. Include "wicket-quickstart-web-fragment.jar" in the "WEB-INF/lib" directory of your application by adding the following fragment in your "pom.xml":

        <dependencies>

            . . .
            <!-- web-fragment -->
            <dependency>
                <groupId>org.glassfish.extras</groupId>
                <artifactId>wicket-quickstart-web-fragment</artifactId>
                <version>1.0</version>
                <scope>runtime</scope>
            </dependency>
        </dependencies>

       . . .

        <repositories>
            <repository>
                <id>maven2-repository.dev.java.net</id>
                <name>Java.net Repository for Maven</name>
                <url>http://download.java.net/maven/2/</url>
            </repository>
        </repositories>

    This file contains only "META-INF/web-fragment.xml" with the following content:

    <web-fragment>
            <filter>
                    <filter-name>wicket.helloworld</filter-name>
                    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
                    <init-param>
                            <param-name>applicationClassName</param-name>
                            <param-value>org.glassfish.samples.WicketApplication</param-value>
                    </init-param>
            </filter>

            <filter-mapping>
                    <filter-name>wicket.helloworld</filter-name>
                    <url-pattern>/\*</url-pattern>
            </filter-mapping>
    </web-fragment>

  3. Create the WAR file without "web.xml" by editing "pom.xml" and adding the following fragment:

          <plugins>
                . . .
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.1-beta-1</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                . . .
          </plugins>

That's it, now you can create a WAR file using "mvn package" and deploy this web application on GlassFish v3 latest promoted build (58 as of today) as explained in TOTD #86.

The updated WAR file structure looks like:

helloworld-1.0-SNAPSHOT
helloworld-1.0-SNAPSHOT/META-INF
helloworld-1.0-SNAPSHOT/WEB-INF
helloworld-1.0-SNAPSHOT/WEB-INF/classes
helloworld-1.0-SNAPSHOT/WEB-INF/classes/log4j.properties
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.class
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.html
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/WicketApplication.class
helloworld-1.0-SNAPSHOT/WEB-INF/lib
helloworld-1.0-SNAPSHOT/WEB-INF/lib/log4j-1.2.14.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-api-1.4.2.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-log4j12-1.4.2.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-1.4.0.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-quickstart-web-fragment-1.0.jar

Notice, there is no "web.xml" and the additional "wicket-quickstart-web-fragment-1.0.jar" and everything works as is!

It would be nice if the next version of wicket-\*.jar can include "META-INF/web-fragment.xml" then everything will work out-of-the-box :)

Here is a snapshot of the deployed application:



Are you deploying your Wicket applications on GlassFish ?


Technorati: totd glassfish v3 wicket javaee6 servlet web-fragment
Comments:

Thanks for keeping us up to date with Java EE and Wicket. Yes I am deploying Wicket on GlassFish. However there is an issue with @EJB annotation, where developer productivity becomes poor, and we need support and clarification there otherwise Wicket is probably not going to co-exist with Glassfish and probably not even with EJB in general. Please refer to https://issues.apache.org/jira/browse/WICKET-2416.

Best regards

Bernard

Posted by Bernard on August 11, 2009 at 07:18 AM PDT #

https://issues.apache.org/jira/browse/WICKET-2416

No dot this time

Posted by Bernard on August 11, 2009 at 07:20 AM PDT #

Bernard, Thanks for your response.

I'm following up with the team and let you know after I hear back.

Posted by Arun Gupta on August 11, 2009 at 08:35 AM PDT #

Nice blog, Arun!

Note that org.apache.wicket.protocol.http.WicketFilter could be simplified substantially by using some of the new Servlet 3.0 registration and lookup APIs.

In its current form, WicketFilter#init attempts to parse the web.xml to see if it contains any <filter-mapping> elements with url patterns for the filter named wicket.helloworld.

Servlet 3.0 would simplify this job. All that is needed is the following code snippet inside WicketFilter#init:

FilterRegistration reg = filterConfig.getServletContext().getFilterRegistration("wicket.helloworld");
if (reg != null) {
Collection<String> urlPatterns = reg.getUrlPatternMappings();
[...]
}

Posted by Jan Luehe on August 11, 2009 at 11:33 AM PDT #

Visa hänsyn till din partners barn om hon/han har barn sedan tidigare. Finns inget vidrigare en make som behandlar barn illa.

Posted by skilsmässa on August 11, 2009 at 08:04 PM PDT #

Post a Comment:
Comments are closed for this entry.
About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today