Using Maven Jetty plugin

Although I am using Maven since a long time I never used the Jetty plugin until recently. To be able to test a REST client I created a servlet which showed me all incoming parameters and headers with the incoming request. To run the servlet in a container I decided to give the Maven Jetty plugin a go.
So first I create a web application by using the specific Maven archetype:

mvn archetype:generate -DgroupId=net.pascalalma -DartifactId=rest-service -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp

This results in the complete project and the following logging:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
Downloading: http://artifactory.redstream.nl/repo/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar
Downloaded: http://artifactory.redstream.nl/repo/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar (4 KB at 5.2 KB/sec)
Downloading: http://artifactory.redstream.nl/repo/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom
Downloaded: http://artifactory.redstream.nl/repo/org/apache/maven/archetypes/maven-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom (533 B at 1.1 KB/sec)
[INFO] Using property: groupId = net.pascalalma
[INFO] Using property: artifactId = rest-service
[INFO] Using property: version = 1.0.0-SNAPSHOT
[INFO] Using property: package = net.pascalalma
Confirm properties configuration:
groupId: net.pascalalma
artifactId: rest-service
version: 1.0.0-SNAPSHOT
package: net.pascalalma
 Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: net.pascalalma
[INFO] Parameter: packageName, Value: net.pascalalma
[INFO] Parameter: package, Value: net.pascalalma
[INFO] Parameter: artifactId, Value: rest-service
[INFO] Parameter: basedir, Value: /Users/pascal/projects
[INFO] Parameter: version, Value: 1.0.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/pascal/projects/rest-service
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.057s
[INFO] Finished at: Sun Feb 03 17:13:33 CET 2013
[INFO] Final Memory: 7M/81M
[INFO] ------------------------------------------------------------------------
MacBook-Air-van-Pascal:projects pascal$ 

Next I added the servlet code to the project:

package net.pascalalma.servlets;

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

/**
 *
 * @author pascal
 */
public class TestRestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("GET method called");
        out.println("parameters:\n " + parameters(request));
        out.println("headers:\n " + headers(request));
    }

    public void doPost(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("POST method called");
        out.println("parameters: " + parameters(request));
        out.println("headers: " + headers(request));
    }

    public void doDelete(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("Delete method called");
    }

    private String parameters(HttpServletRequest request) {
        StringBuilder builder = new StringBuilder();
        for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
            String name = (String) e.nextElement();
            builder.append("|" + name + "->" + request.getParameter(name)+"\n");
        }
        return builder.toString();
    }

    private String headers(HttpServletRequest request) {
        StringBuilder builder = new StringBuilder();
        for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) {
            String name = (String) e.nextElement();
            builder.append("|" + name + "->" + request.getHeader(name)+"\n");
        }
        return builder.toString();
    }
}

And configure the servlet in the ‘web.xml’. By the way the generated ‘web.xml’ wasn’t able to be shown in my Netbeans version (v7.2.1). I got the message:

Web application version is unsupported. Upgrade web.xml to version 2.4 or newer or use previous version of NetBeans

To fixed this I modified the web.xml so it starts with the following declaration of namespaces:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

Next add the servlet to the modified ‘web.xml’:

<?xml version="1.0" encoding="UTF-8"?>
...
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>TestRestServlet</servlet-name>
    <servlet-class>net.pascalalma.servlets.TestRestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestRestServlet</servlet-name>
    <url-pattern>/TestRestServlet</url-pattern>
  </servlet-mapping>
...

Now everything is ready to test the servlet. As I said before I am going to use the Jetty plugin for this. To add the plugin to the project simply put the following in your ‘pom.xml’:

<plugins>
  <plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
      <scanIntervalSeconds>10</scanIntervalSeconds>
      <contextPath>/</contextPath>
      <scanIntervalSeconds>10</scanIntervalSeconds>
      <stopKey>STOP</stopKey>
      <stopPort>8005</stopPort>
      <port>8080</port>
    </configuration>
  </plugin>
</plugins>

Now I can run the command ‘mvn jetty:run’ in my terminal to have the container running the servlet. The log should end with something like:

....
2013-02-19 09:54:53.044:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 10 seconds.</code>

Now if you open a browser and go to the this url ‘http://localhost:8080/TestRestServlet?bla=true&#8217; you will see the servlet in action and outputting to the browser:

GET method called
parameters:
|bla->true

headers:
|DNT->1
|Host->localhost:8080
|Accept->text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|Accept-Charset->ISO-8859-1,utf-8;q=0.7,*;q=0.3
|Accept-Language->en-US,en;q=0.8
|User-Agent->Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
|Connection->keep-alive
|Cache-Control->max-age=0
|Accept-Encoding->gzip,deflate,sdch

One note: As you can see in the plugin configuration I have added a few extra parameters for my convenience. So will the container check every 10 seconds for changes in the servlet, so I don’t have to restart the Jetty container after each change of the servlet. To stop the container you can now enter the command ‘mvn jetty:stop -DstopPort=8005 -DstopKey=STOP’ in another terminal session. By the way, make sure you name the plugin ‘jetty-maven-plugin’ and not ‘maven-jetty-plugin’ because then you will be using an old version of the plugin which doesn’t pickup the configuration parameters (yes, very confusing and frustrating as I found out).

About Pascal Alma

Pascal is a senior IT consultant and has been working in IT since 1997. He is monitoring the latest development in new technologies (Mobile, Cloud, Big Data) closely and particularly interested in Java open source tool stacks, cloud related technologies like AWS and mobile development like building iOS apps with Swift. Specialties: Java/JEE/Spring Amazon AWS API/REST Big Data Continuous Delivery Swift/iOS
This entry was posted in Maven, Web Service and tagged . Bookmark the permalink.