Debug Servlet Webapp deployed to Jetty using Maven and Eclipse

This is a guide for the Eclipse configurations in order to debug a webapp deployed to Jetty introduced as a Maven plugin. The setup has been described to this article.

Since we don’t use the Eclipse WTP tooling system to our advantage, there is a bit of manual work so that to setup the parameters and debug the webapp remotely.

First we need to setup the maven goal:

mvn jetty:run

to be remote debugging-aware. To do so we go to “External Tools > External Tools Configuration”, creating a new configuration setting and setting the “Location:” section to the full path of the

mvn

executable. The “Working Directory” needs to point to our Eclipse project. As an argument we are setting:

jetty:run

Finally in the “Environment” tab we need to setup the followings as variable/value:

MAVEN_OPTS / -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y

 

Finally we need to setup a new “Debug > Debug Configurations.. > Remote Java Application” configuration setting, pointing to our project and making sure the port is set to 4000 to match the setting we’ve specified above.

Advertisements

Servlet deployed to Jetty using Maven and Eclipse

That’s a quick guide to setup a test Servlet running on the lightweight Jetty web container, embedded and fired as a Maven plugin.

First off, create a New Maven Project in Eclipse.

Then define the following POM file:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.wordpress.dimitrisli</groupId>
  <artifactId>TestServletInJettyMaven</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <build>
  	 <finalName>TestServletInJettyMaven</finalName>
  	<plugins>
    <plugin>
    	<artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
  		<plugin>
  			<groupId>org.mortbay.jetty</groupId>
  			<artifactId>jetty-maven-plugin</artifactId>
  			<version>8.0.0.M3</version>
  			 <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <webAppConfig>
                        <contextPath>/TestServletInJettyMaven</contextPath>
                    </webAppConfig>
                </configuration>
  		</plugin>
  	</plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
    </dependency>
    <dependency>
    	<groupId>javax.servlet</groupId>
    	<artifactId>javax.servlet-api</artifactId>
    	<version>3.0.1</version>
    	<scope>provided</scope>
    </dependency>
  </dependencies>
</project>

Then, it’s time for our Servlet class:

package servletService;

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;


public class TestServletInJettyMaven extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("Get method called");
		out.println("parameters:"+parameters(request));
		out.println("headers:"+headers(request));
	}
	
	@Override
	protected 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));
	}
	
	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));
		}
		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));
		}
		return builder.toString();
	}
}

And finally our web.xml that we need to define under the new folder structure: src/main/webapp/WEB-INF/web.xml:

<?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>Test Servlet In Jetty Maven</display-name>
        <description>Test Servlet In Jetty Maven Service
    </description>

    <servlet>
        <servlet-name>TestServletInJettyMaven</servlet-name>
        <servlet-class>servletService.TestServletInJettyMaven</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TestServletInJettyMaven</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

To build the code and deploy to jetty, from the Run configurations of Eclipse, create a new Maven run configuration, make it point to your newly created project under the Base Directory section and set as Goals:

-Djetty.port=8081 jetty:run

Now connect to the following url to test the connection:

http://localhost:8081/TestServletInJettyMaven/test

For downloading the code of this sceletal bootstrap have a look at this Mercurial repository

Singleton Design Pattern VS Spring Singleton Scope

  • First off, the Singleton design pattern is.. well.. a design pattern whereas Spring’s singleton refers to the singleton scope which by the way is the default bean scope in Spring.
  • The Singleton design pattern is effectively a unique instance of an object per class loader whereas Spring singleton scope ensures the presence of a unique bean per application context.
  • Spring’s singleton scope is uniquely identified by the bean’s id meaning that we can have several beans of the same class type with different ids.
  • Spring’s singleton scoped bean is nothing more than a reference to an object, which, once instantiated, it gets cached by the IoC container and provided upon request. So in short the Spring container that deals with the beans lifecycle is handling internally the bean references and make a reference look like a singleton design pattern-ed object although it’s not.
  • We can have a situation where we inject a prototype-scoped bean into a singleton-scoped bean. That would mean, every time we are requesting the singleton-scoped bean a new object will be injected as a dependency for the prototyped-scoped dependency.

Java Singleton Design Pattern Example

Eagerly created singleton non-multithreaded version:

public class Singleton {

	public static Singleton singleton = new Singleton();
	
	private Singleton(){}
}

In the above example it is evident that the public static field is exposing the singleton upon creation. The constructor is of course private and concealed from the outer world.

Eagerly created singleton multithreaded version:

public class Singleton {

	public static volatile Singleton singleton = new Singleton();
	
	private Singleton(){}
}

The only addition in the above code is the volatile identifier that is forcing all threads that request read to this variable to cross the memory barrier to the main memory and not rely on JVM registry and cache-local optimisations.

Lazily created singleton multithreaded version:

public class Singleton {

	private static volatile Singleton singleton;
	
	private Singleton(){}
	
	public static Singleton getSingleton(){
		if(singleton==null)
			singleton = new Singleton();
		return singleton;
	}
}

In the above example note that the static field has been changed to private scope so only accessible from inside the object. Also the field is set to null by default postponing the instantiation when the singleton is first needed. Moreover, it has been added a factory method lazily instantiates the singleton.