Adding a Web Module to a Gradle Project

Tuesday, January 31, 2012

It’s common in a lot of projects the need to separate parts of the system into their own modules. Gradle is well suited for this approach by allowing a single project to have many logically different modules. This post is continuation of my previous post Building With Gradle.

In this post we’ll create a second module for deploying to a servlet container. We’ll call this module example-web and it will produce a WAR artifact for deployment in Tomcat, Jetty, or any other suitable application server.

So lets roll…

(more…)

Building with Gradle

Thursday, January 26, 2012

Recently I was on a project that needed to chose a build system. We looked at the usual suspects, ant and maven and after having less then wonderful experiences with both I looked for an alternative. That’s where Gradle came in. In this post I’m going to go through getting started on a simple project. In subsequent posts I plan on increasing the complexity and offer solutions to common issues found on a project.

Why choose gradle

I’ll assume since you’re here that you have an interest in gradle and may have already scoured the internet for comparisons of it with other popular build tools (Ant and Maven).  Below are some of the reasons why I chose Gradle for my project and not the others.

1. Gradle is built on top of a full fledged programming language (groovy) and has direct access to all of it’s goodies.  No reliance on plugins for custom scripting (Maven, Ant plugin), no overhead of creating custom Java classes or plugins, and finally no angle bracket soup (ant scripting).

2. Gradle out of the box has support for dependency management via Ivy and is compatible with all Maven repositories including enterprise ones (Artifactory, Nexus, etc.).

3. Gradle supports multi-module projects without having to reinvent the wheel (ant).

4. Finally, Gradle is extremely flexible allowing for just about any build configuration you could imagine unlike other build tools (I’m looking at you Maven).

(more…)

Creating a Spring @StrictDateTimeFormat Annotation

Thursday, January 19, 2012

Spring Formatters and Converters make it easy to annotate fields for conversion from Objects to Strings, and are especially useful in web apps. But there is no easy or straightforward way to strictly validate the String before parsing into an object, without creating a custom Formatter. Here is a reusable solution that uses a RegexParserDecorator to decorate any Spring Formatter to apply a regex pattern, in turn creating a @StrictDateTimeFormat annotation as an example implementation.

A little background: Spring 3.0 brought the Converter and Formatter framework with a concise @DateTimeFormat annotation, simplifying the Date to Object conversion that previously took custom binders or other wiring code. With @DateTimeFormat you can easily supply a String pattern used to parse and print a Date (or joda DateTime) object. However, the annotation does not strictly validate the String before converting to a Date. For instance, supplying a MM/dd/yyyy pattern does NOT enforce a 4 digit year. Instead a 2 digit year will be accepted and parsed using the SimpleDateFormat rules. Similar loose checking goes for 1 digit days and months, and also the slash character used as a separator. It would be easy to just throw the @Pattern tag onto your Date field except that @Pattern is only allowed on String fields. Combining @Pattern and @DateTimeFormat is what drove the creation of @StrictDateTimeFormat:


//sample usage using defaults for regex and pattern
@StrictDateTimeFormat
private DateTime birthday;

Read more below for a discussion and snippets of code, and the entire codeset with comments is available on github.
(more…)

Introduction to Servlet 3.0

Monday, January 16, 2012

Earlier in 2011 the Apache group released Tomcat v7 on the waiting Servlet world. With this came featured support for Servlet 3.0. In some discussions it seems that Servlet 3.0 was supposedly supported by later versions of Tomcat v6, but I can’t find anything more than a few scattered mentions; mostly wishful thinking, it seems. With Tomcat v7, we can now get Servlet 3.0 support! It also supports JSP v2.2 and EL v2.2, but for now I just want to poke at a few niceties provided with Servlet 3.0.

Annotations

One very nice thing Servlet 3.0 brings us is a set of annotations to declare Filters and Servlets and Listeners. With these annotations, the configuration of applications is removed from the web.xml file and put into the application’s JARs and WEB-INF/classes.  This is an exciting feature because it also allows you to package your Servlets,  Filters, and Listeners into JAR files and include them in your web application simply by including the JAR file in the WEB-INF/lib folder of the application. Packaging and fragmenting an application is a topic for another day; let’s just focus on the annotations for the moment.

For those familiar with annotated frameworks such as Spring, it shouldn’t be too difficult to see the benefit of annotating code instead of adding configuration to the web.xml file. There’s the easy spot of “ease,” as it simply doesn’t need to be done. There’s a simple case for “error-proofing” as the annotation should be close enough to the code that it alleviates some of those errors.

Filters

Typically Filters are declared in the web.xml file in the following fashion:

<filter>
  <filter-name>site-filter</filter-name>
  <filter-class>foo.SiteFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>site-filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

It’s a bit of XML just to relate a URL pattern (or few) to a class. Of course, additional information can be provided, including initialization parameters for the filter class. The filter class needs to then implement the javax.servlet.Filter interface, and contain a few methods to satisfy the Filter interface. This doesn’t change much in the Servlet 3.0 annotation scheme.

To use a Servlet 3.0 annotated filter, the class must still implement the Filter interface and contain the methods to satisfy the interface, but rather than all of that XML configuration, the annotation @WebFilter() can be added to the class definition, and its parameters added as attributes to the Filter. Here’s what it takes to replace that block of XML:

@WebFilter( "/*" )
public class SiteFilter implements Filter {
  @Override
  public void destroy() {
  }
  @Override
  public void doFilter(final ServletRequest servletRequest,
                       final ServletResponse servletResponse,
                       final FilterChain filterChain)
         throws IOException, ServletException {
    // Whatever you need to do
    filterChain.doFilter(servletRequest, servletResponse);
  }
  @Override
  public void init(final FilterConfig filterConfig)
         throws ServletException {
  }
}

Of course, as with the XML, additional values can be applied.

@WebFilter(urlPatterns = { "/specific","/url","/patterns.ext" },
           initParams={@WebInitParam(name="something",value="cool")})

The sample above allows our Filter only to match three specific URL patterns (since there’s no wildcard), and adds a cool value to the initialization values.

Including Other Filters

This can also be applied to older Filters that are not annotated. For example, I frequently use the Tuckey UrlRewriteFilter to ensure my application doesn’t throw itself for a loop by adding the session ID to the returned URL. It’s a simple Filter, expressed in some XML included with the application (taken from their examples):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite>
<!-- PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd"-->
<urlrewrite>
  <outbound-rule encodefirst="true">
    <name>Strip URL Session ID's</name>
    <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
    <to>$1$2$3</to>
  </outbound-rule>
</urlrewrite>

This strips the jsessionid parameter from any outbound data returned to the browser; this stops the URL from changing to /somepath.ext?jsessionid=breakmenow which can cause relative URLs in the application to end up wrong, like /somepath.ext?jsessionid=breakmenow/images/reallywanted.jpg. To implement this the old way, you’d specify the Filter in the web.xml, as the following (from their documentation) demonstrates:

<filter>
<filter-name>UrlRewriteFilter</filter-name>
  <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>UrlRewriteFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

To implement this annotation-unaware Filter into your annotated application, though, simply make a Filter that overrides the UrlRewriteFilter, and pass it the URLs to filter:

@WebFilter(urlPatterns = { "/*" },
           dispatcherTypes = { DispatcherType.REQUEST, DispatcherType.FORWARD })
public class RewriteFilter extends UrlRewriteFilter {
}

No other content in the class is required, and the now annotated Filter is added without any inclusion in the web.xml file.

Listener

Listeners are defined much the same way. As before, the old way of defining a Listener was to declare it in the web.xml file

<listener>
  <listener-class>foo.SiteListener</listener-class>
</listener>

The listeners define classes that the web app container will find and start. As before, the class must implement an appropriate interface; one of the javax.servlet.Servlet*Listeners. And, of course, it must implement the methods to satisfy the interface.

To use an annotated Listener, implement the desired Listener, satisfy it with the required methods, and annotate it with the @WebListener annotation.

@WebListener()
public class SiteListener implements ServletRequestListener {
  @Override
  public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
  }
  @Override
  public void requestInitialized(ServletRequestEvent servletRequestEvent) {
  }
}

The annotation doesn’t require any parameters. The only parameter it allows is an optional description of the Listener.

Including Other Listeners

As with Filters, it’s easy to include Listeners that aren’t annotated. For example, to include Apache Tiles in your web.xml, you can define the Listener using the XML (from their documentation):

<listener>
  <listener-class>org.apache.tiles.web.startup.simple.SimpleTilesListener</listener-class>
</listener>

Or using annotations, simply extend the Tiles Listener you want to use, and annotate it appropriately.

@WebListener
public class TilesListener extends SimpleTilesListener {
}

This way you can contain the configuration entirely in software.

Servlet

Servlets are mapped much the same way Filters are mapped. Traditionally, the web.xml will define a Servlet and Servlet mappings to tie URLs to the correct Servlet.

<servlet>
  <servlet-name>SiteServlet</servlet-name>
  <servlet-class>foo.SiteServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>SiteServlet</servlet-name>
  <url-pattern>/mapping</url-pattern>
</servlet-mapping>

The Servlet then needs to extend the class javax.servlet.http.HttpServlet. No methods are required, but generally either or both of the doGet() or doPost() methods are implemented to handle the request action.

To use the Servlet 3.0 annotation for a Servlet, the HttpServlet class must still be implemented, and the annotation @WebServlet needs to be applied. The @WebServlet annotation requires only one attribute as it needs to know at least one URL to which the Servlet will be mapped.

@WebServlet("/mapping")
public class SiteServlet extends HttpServlet {
  @Override
  protected void doPost(final HttpServletRequest httpServletRequest,
                        final HttpServletResponse httpServletResponse)
             throws ServletException, IOException {
  // Do your stuff
  }
}

Of course, mutliple URLs can be added, as with the Filter, by specifying the urlPatterns parameter.

Using Other Servlets

With many frameworks, like Spring MVC or Apache Struts, there’s only one Servlet. That Servlet handles all of the processing of requests, routing them to the appropriate Action or Controller as necessary. As with the Filter and Listener annotations, a simple annotation can bring that third-party Servlet into the application with @WebServlet annotations. From the Spring documentation, here’s how to set up a basic DispatcherServlet in the web.xml file.

<servlet>
  <servlet-name>example</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>example</servlet-name>
  <url-pattern>*.form</url-pattern>
</servlet-mapping>

Here’s how to do the same using Servlet 3.0 annotations.

@WebServlet(urlPatterns={"/*.form"}, loadOnStartup=1)
public class SpringDispatcherServlet extends DispatcherServlet {
}

With this, the Spring DispatcherServlet is mapped to accept all URLs ending in .form, and it will be loaded when the application starts (instead of waiting for the first request). As with @WebFilter annotations, the @WebServlet also accepts init parameters, so those can also be added to help configure the application.

Some Limitations

One thing that some of the other frameworks like Spring bring is an ability to map the URL to methods with their annotations. While Servlet 3.0 annotations allow mapping more than one URL to a Servlet class, it is still up to the developer to decipher the URL in the Servlet, as necessary. This is no different than “usual” Servlet development where more than one URL is mapped to a Servlet; inside the Servlet the request path or URI or other mechanism can be used to determine by which the visitor arrived to the Servlet.

Additionally, Servlet 3.0 doesn’t bring any tools to map elements such as GET or POST parameters to method parameters. The same Servlet digestion of parameters occurs, and they’re all Strings until converted. It’s up to the developer to handle all of the parameter transformation.

Generating Excel from Grails

Thursday, January 12, 2012

Most developers do their best to avoid working in Excel, but it is often necessary to produce reports or other output in Excel format.  Often times we resort to simple CSV files, or raw data put into an Excel format.  While this handles most basic cases, it’s not always enough.   If you want to have formatting, formulas, merging etc, you are going to need to use an Excel specific library.

There are two main libraries for creating Excel documents from Java/Groovy; POI and JXL.  After some research, I came to the conclusion that JXL is more up-to-date and powerful.  It is a Java library though.  As such, it is strongly typed with a lot of extra syntax that those of us developing in Groovy like to avoid.  To get around this, I created the Grails JXL plugin.

The plugin is a wrapper for the library, but it also adds some nice builder-like syntax to create Excel documents.  For example, to create a workbook with a single worksheet and a few cells you can write:

workbook('/path/to/test.xls') {
    sheet('SheetName') {
        cell(0,0,'Column 1').bold().center()
        cell(1,0,'Column 2').bold().center()
        cell(0,1,'Value 1').left()
        cell(1,1,'Value 2').left()
    }
}

Or if you prefer, you can add the data as a map

workbook('/path/to/test.xls') {
    sheet('SheetName') {
        addData([
            ['Column 1','Column 2'],
            ['Value 1','Value 2']
       ])
    }
    (0..1).each { cell(it,0).bold().center() } 
    (0..1).each { cell(it,1).left() }
}

To get this builder syntax, you simply have to use the Mixin grails.plugin.jxl.ExcelBuilder.

    @Mixin(ExcelBuilder)
    class MyBuilder {

Notice that columns and rows are 0 indexed, and that the cell method can be used to set the cell value when one is provided, or get the current cell when no value is provided.  In either case you can use provided methods to do formatting.

The plugin provides many built in methods for formatting, such as bold(), italic(), thinBorder(), dottedBorder() etc.  It also give access to all of the JXL functionality, by allowing you to set properties of WritableFont and WritableFormat directly on the cell, such as

    cell(0,0,"foo").pointSize = 16

The plugin also allows you to create Excel formulas, as in

    cell(3,6, formula.sum(formula.range(3,0,3,5)))

which generates a cell with the formula =SUM(A4:F4). The formula object supplies a range function to create the Excel formatted range. All other functions dynamically create the Excel function with the same name; in this case sum.

The Grails JXL plugin takes advantage of a great library and Groovy’s dynamic nature to give a more convenient way to generate formatted Excel documents.  Feedback is very welcome, as this plugin is still in it’s early stages. For more detailed information, check out the wiki on github.