Thursday, May 31, 2012

Spring WebApplicationInitializer and programmatic support for web.xml file

Servlet 3.0 provides a programmatic way to specify and configure the contents of a web.xml file.

A servlet 3.0 based web application can implement a ServletContainerInitializer interface, which is explicitly passed a ServletContext which is a runtime representation of the container, to be used for configuring the servlets, filters, listeners and other contents normally specified through a typical web.xml file.

If a custom ServletContainerInitializer is provided, the implementation class name has to be declared in a META-INF/services/java.servlet.ServletContainerInitializer file in the classpath.

Spring 3.1+ makes this a process a little easier by providing an implementation of ServletContainerInitializer called the SpringServletContainerInitializer, registers this implementation through the META-INF/services/java.servlet.ServletContainerInitializer file in the spring-web module, and in turn delegates the responsibility of configuring the ServletContext to classes implementing a custom Spring interface called WebApplicationInitializer.

Essentially from a web application developers perspective the only thing that needs to be done is to implement a WebApplicationInitializer, and configure the ServletContext in the implementation. This is how a custom WebApplicationInitializer for a web application looks like for a typical Spring Application:

public class CustomWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
  rootContext.setConfigLocations(new String[]{"classpath*:META-INF/spring/applicationContext-security.xml", "classpath*:META-INF/spring/applicationContext.xml"});

  container.addListener(new ContextLoaderListener(rootContext));

  ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", DispatcherServlet.class);
  dispatcher.setInitParameter("contextConfigLocation", "/WEB-INF/spring/webmvc-config.xml");
  dispatcher.addMapping("/");

  container.addFilter("Spring OpenEntityManagerInViewFilter", org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.class)
   .addMappingForUrlPatterns(null, false, "/*");

  container.addFilter("HttpMethodFilter", org.springframework.web.filter.HiddenHttpMethodFilter.class)
   .addMappingForUrlPatterns(null, false, "/*");

  container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
     .addMappingForUrlPatterns(null, false, "/*");

  FilterRegistration charEncodingfilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
  charEncodingfilterReg.setInitParameter("encoding", "UTF-8");
  charEncodingfilterReg.setInitParameter("forceEncoding", "true");
  charEncodingfilterReg.addMappingForUrlPatterns(null, false, "/*");
 }
}

A web.xml is still required though, to configure some things which cannot be completely configured using this mechanism, the stripped down web.xml looks like this:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false">

    <display-name>my app</display-name>
    
    <description>my app</description>

    <context-param>
        <param-name>defaultHtmlEscape</param-name>
        <param-value>true</param-value>
    </context-param>
    
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/uncaughtException</location>
    </error-page>
    
    <error-page>
        <error-code>404</error-code>
        <location>/resourceNotFound</location>
    </error-page>
</web-app>

Make a note of the version attribute specified as 3.0, and the schema location being specified as "http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd", these are what trigger the container to consider this as a Servlet 3.0 web application.

That is basically it, with these in place the application can be considered to be configured - mostly without a web.xml file!

References:
http://blog.springsource.org/2011/06/10/spring-3-1-m2-configuration-enhancements/
Greenhouse application at Github - https://github.com/SpringSource/greenhouse - look in the servlet3 branch

Wednesday, May 30, 2012

IndyJUG - Session on SOLID principles

Today I attended a session on SOLID Object Oriented Principles at Indianapolis JUG(Indy JUG), the talk was by Matt Stine.

The talk was a very good aggregation of material available on SOLID from Bob Martin's(Uncle Bob) site, along with some "effective" examples thrown in from Effective Java Book. Matt was engaging throughout the almost 2 hour session, and I personally got a good deal of information. Just to summarize:

S - Single Responsibility Principle - An Object should have only one reason to change.
O - Open/Closed Principle - A software entity(module, library, routine) should be closed to any modification but be open to extension
L - Liskov Substitution Principle - Derived classes should be substitutable for the base classes
I - Interface Segregation Principle - Having more fine grained interfaces over fat interfaces
D - Dependency Inversion Principle - Depending on abstractions, not concrete implementations.

Monday, May 28, 2012

Recursive Generic definitions in Java

I can think of two recursive Generic definitions common in java:
1. For Comparable types -
<T extends Comparable<T>>

Using this a sort API would look something like this:
<T extends Comparable<? super T>> void sort(T[] a);


2. For Enum types:
<E extends Enum<E>>

Using this a utility function in EnumSet looks like this:
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2)

Sunday, May 13, 2012

Spring annotation alternative for init-method attribute

Strangely, Spring natively does not provide an annotation support for the init-method attribute in xml. Consider a simple service:

import org.springframework.stereotype.Service;
public class BookServiceImpl implements BookService{
 
 public void init(){
  // init-method..
 }
 
 @Override
 public void buyBook() {
  //Implementation..
 }
}

The declaration for this service in a Spring context file would have been along these lines:
<bean name="bookService" class="org.bk.samples.types.BookServiceImpl" init-method="init"/>

the init-method contains the method name to be invoked post instantiation and after all the properties of the beans have been wired in.

The annotation equivalent of this is using @javax.annotation.PostConstruct annotation, which is part of the Common Annotations for Java.

So the equivalent annotation based annotation would be the following.

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl implements BookService{
 
 @PostConstruct
 public void init(){
 }
 
 @Override
 public void buyBook() {
  //Implementation..
 }
}

Thursday, May 10, 2012

Injecting in HttpServletRequest to a Spring Bean

This is a little counter intuitive, you can actually inject in HttpServletRequest into any Spring component!

For eg:

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;

public class HttpRequestServiceImpl implements HttpRequestService{

 @Autowired private HttpServletRequest httpServletRequest;
 @Override
 public String getAttribute(String name) {
  return (String)this.httpServletRequest.getAttribute(name);
 }
}

So when multiple requests come to this service, how is the correct httpServletRequest corresponding to the user request injected into this service object. The answer is that a real HttpServletRequest is not really injected, only a proxy is injected in. The proxy is internally a reference to RequestContextHolder which at some point binds the HttpServletRequest to a threadlocal variable.

Wednesday, May 2, 2012

Java Executor with Spring xml configuration - A Sample

Consider a simple flow - I need to generate a report by aggregating together the different sections of a report.


A client call, say, is along these lines, for a report with 5 different sections:

ReportRequestPart part1 = new ReportRequestPart(Section.HEADER, context);
ReportRequestPart part2 = new ReportRequestPart(Section.SECTION1, context);
ReportRequestPart part3 = new ReportRequestPart(Section.SECTION2, context);
ReportRequestPart part4 = new ReportRequestPart(Section.SECTION3, context);
ReportRequestPart part5 = new ReportRequestPart(Section.FOOTER, context);

requestParts.add(part1); 
requestParts.add(part2);
requestParts.add(part3);
requestParts.add(part4);
requestParts.add(part5);
ReportRequest reportRequest  = new ReportRequest(requestParts );
reportGenerator.generateReport(reportRequest);

Here ReportGenerator is the service class responsible for generating the report given the sections of the report.

The part of the report for each section can be generated independently, so a java based concurrent implementation would start by defining a task - which is done by implementing a Runnable or Callable interface. Callable interface is implemented for tasks that return a result, like in this case where I want to return a part of a report from a task and put the different parts together into a report.

This is how my Report part task looks:

public class ReportPartRequestCallable implements Callable<ReportPart> {
 private final ReportRequestPart reportRequestPart;
 private final ReportPartGenerator reportPartGenerator;

 public ReportPartRequestCallable(ReportRequestPart reportRequestPart, ReportPartGenerator reportPartGenerator) {
     this.reportRequestPart = reportRequestPart;
     this.reportPartGenerator = reportPartGenerator;
    }

    @Override
    public ReportPart call() {
    return this.reportPartGenerator.generateReportPart(reportRequestPart);
    } 
}

Now given this task my report generator using Java Executor would start by creating a threadpool:
private ExecutorService executors = Executors.newFixedThreadPool(10);

In this instance, I am using the Executors utility class to create a fixed sized thread pool.
The next job is to simply submit the individual parts of the report request to this thread pool and collect back the results:
@Override
public Report generateReport(ReportRequest reportRequest) {
 List<Callable<ReportPart>> tasks = new ArrayList<Callable<ReportPart>>();
 List<ReportRequestPart> reportRequestParts = reportRequest.getRequestParts();
 for (ReportRequestPart reportRequestPart : reportRequestParts) {
  tasks.add(new ReportPartRequestCallable(reportRequestPart, reportPartGenerator));
 }

 List<Future<ReportPart>> responseForReportPartList;
 List<ReportPart> reportParts = new ArrayList<ReportPart>();
 try {
  responseForReportPartList = executors.invokeAll(tasks);
  for (Future<ReportPart> reportPartFuture : responseForReportPartList) {
   reportParts.add(reportPartFuture.get());
  }

 } catch (Exception e) {
  logger.error(e.getMessage(), e);
  throw new RuntimeException(e);
 }
 return new Report(reportParts);
}

Here I am using the invokeAll method to kick off the tasks and then using Future.get to join the result together.

Springs abstraction to java Executor is the TaskExecutor, TaskExecutor however cannot be used for executing tasks which return a result(Callable), it can only execute Runnable tasks, which don't return result. So if I want to inject in a Executor to my report generator, this is how I would go about it:
<bean name="taskExecutorBasedReportGenerator" class="org.bk.sisample.taskexecutor.TaskExecutorsBasedReportGenerator">
     <property name="executors">
      <bean class="java.util.concurrent.Executors" factory-method="newFixedThreadPool">
       <constructor-arg value="10"></constructor-arg>
      </bean>
     </property>
     <property name="reportPartGenerator" ref="reportPartGenerator"/>
    </bean>