Chapter 6: Web Development | Sonatype Maven Cookbook

Web Development

6.1 Running a Web Application in a Servlet Container

6.1.1. Task

You need to run a web application in a servlet container.

6.1.2. Action

Configure your web application's Maven project to include the Maven Jetty plugin as shown in the following POM:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0 </modelVersion>
    <groupId>org.sonatype.mcookbook </groupId>
    <artifactId>sample-web </artifactId>
    <packaging>war </packaging>
    <version>1.0-SNAPSHOT </version>
    <name>sample-web Maven Webapp </name>
    <url>http://maven.apache.org </url>
    <dependencies>
        <dependency>
            <groupId>junit </groupId>
            <artifactId>junit </artifactId>
            <version>3.8.1 </version>
            <scope>test </scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet </groupId>
            <artifactId>servlet-api </artifactId>
            <version>2.5 </version>
        </dependency>
    </dependencies>
    <build>
        <finalName>sample-web </finalName>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty </groupId>
                <artifactId>maven-jetty-plugin </artifactId>
                <version>6.1.22 </version>
            </plugin>
        </plugins>
    </build>
</project>

To start the web application in Jetty, run the run goal from the Maven Jetty plugin by running mvn jetty:run.

$ mvn jetty:run

Using a web browser to navigate to http://localhost:8080/sample-web/ to interact with the web application.

6.1.3. Detail

Consider a simple web application with a single index.jsp page that contains a form and a single Servlet that calculates a number from the Fibonacci sequence.

Example 6.1. Simple Form Accepting an Index to Pass to the Fibonacci Servlet

<html>
<body>
<h2>Fibonacci Page</h2>
<form action="fib" method="GET">
<p>Fetch Fibonacci Sequence Index:
<input type="text" name="index" size="5"/></p>
<input type="submit" value="Calculate"/>
</form>
</body>
</html>

The following class is the Servlet which calculates the Fibonacci sequence. It takes a single parameter index and prints the number at the specified position of the Fibonacci sequence.

Example 6.2. Fibonacci Servlet which Calculates a Number from the Fibonacci Sequence

package org.sonatype.mcookbook;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FibonacciServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int index = Integer.parseInt(req.getParameter("index"));
        resp.getWriter().write(fib(index) + "");
        resp.getWriter().flush();
        resp.getWriter().close();
    }

public long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }
}

The following web.xml configures the FibonacciServlet to respond to the request path /fib.

Example 6.3. Web Application Descriptor for sample-web

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>fibonacci</servlet-name>
        <servlet-class>org.sonatype.mcookbook.FibonacciServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>fibonacci</servlet-name>
        <url-pattern>/fib</url-pattern>
    </servlet-mapping>
</web-app>

After running mvn:jetty, you can load the initial form by going to http://localhost:8080/sample-web/index.jsp. Populating the form with an index and pressing calculate will load the Fibonacci servlet and print out the number at that position of the sequence.

6.2. Starting a WAR Dependency in a Servlet Container

6.2.1. Task

You need to configure Maven to download and start a web application from a repository manager.

6.2.2. Action

Use the Maven Dependency plugin to copy the web application's WAR artifact to your project. Then configure the Maven Jetty plugin to execute the web application using the plugin's dependencies element to configure the classpath for Jetty.

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.sonatype.mcookbook</groupId>
    <artifactId>start-jackrabbit</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>start-jackrabbit</name>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>org.apache.jackrabbit</groupId>
                                    <artifactId>jackrabbit-webapp</artifactId>
                                    <version>1.6.0</version>
                                    <type>war</type>
                                    <overWrite>true</overWrite>
                                    <destFileName>jackrabbit-webapp.war</destFileName>
                                </artifactItem>
                            </artifactItems>
                            <outputDirectory>
                                ${project.build.directory}/war
                            </outputDirectory>
                            <overWriteReleases>true</overWriteReleases>
                            <overWriteSnapshots>true</overWriteSnapshots>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.22</version>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <configuration>
                            <contextPath>jackrabbit</contextPath>
                            <daemon>false</daemon>
                            <webApp>${project.build.directory}/war/jackrabbit-webapp.war</webApp>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.jackrabbit</groupId>
                        <artifactId>jackrabbit-webapp</artifactId>
                        <version>1.6.0</version>
                        <type>war</type>
                    </dependency>
                    <dependency>
                        <groupId>javax.jcr</groupId>
                        <artifactId>jcr</artifactId>
                        <version>2.0</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

To download the Jackrabbit web application and execute it in Jetty, copy the POM to an empty directory and run mvn clean dependency:copy jetty:run-war.

$ mvn clean dependency:copy jetty:run-war

Once Maven has started Jetty with the jackrabbit-webapp.war JAR, go to a web browser and open http://localhost:8080/jackrabbit. You should see the Apache Jackrabbit administrative web interface.

Note

The first time you start the Jackrabbit web application, it will print an exception stack trace as it tries to locate a Jackrabbit database. This stack trace disappears once you load the Jackrabbit administrative interface and create a new Jackrabbit database.

While this isn't the most straightforward use of a Maven POM, it does demonstrate the power of using Maven's dependency management and plugin configuration to distribute the settings necessary to execute a web application.