Thursday, March 20, 2014

Book Review: Programming Groovy 2 Dynamic Productivity for the Java Developer

Overview
"Programming Groovy 2 Dynamic Productivity for the Java Developer" is Dr. Venkat Subramaniam's latest book covering Groovy and important features of this dynamic language.  The book goes into detail on how to use many of the dynamic features of the language and can help make you more productive with the language.

The book is broken down into 4 parts (see below), with 19 chapters covering approximately 300 pages.  I would not suggest this book as an introduction to the Groovy language, but once you are past the intro-level, this book is a must-have!

Contents

  • Part 1 Beginning Groovy  includes Getting Started, Groovy for Java Eyes, Dynamic Typing, Closures and working with Strings and Collections
  • Part 2 Using Groovy includes Exploring the GDK  and working with XML, Databases, Scripts and Classes
  • Part 3 MOPping Groovy includes 6 chapters on working with the MOP in Groovy
  • Part 4 Using Metaprogramming includes chapters on Groovy Builders, Unit Testing and Mocking and Creating DSLs in Groovy

Pros

  • Excellent coverage on the dynamic features of the Groovy language, including the MOP and Metaprogramming.  
  • Examples are short and to-the-point!  You are not forced to read thru the creation of some sample application being created throughout the reading of the book.  Just enough code to get the point across, and as with almost all books, the code is downloadable. 

Cons

  • The book could have been shorter without a lot of the 'introductory' material from Part 1.  The problem there is, that would cut about 125 pages from the book and I would guess the publishers have some 'bare minimum number of pages' for their books.   

Conclusion
Another awesome publication from Venkat.  A "must have" for anyone wanting to improve their Groovy Kung-Fu.  Venkat covers all the cool features of Groovy in an easily understandable way.

I have bought and read a lot of technical books thru the years, but only had 1 that I carried in my briefcase every day.  Now its time to add another book to the briefcase - Groovy 2 Dynamic Productivity for the Java Developer, and I don't even get to use Groovy in my day job!

Tuesday, March 11, 2014

Parameterized JUnit tests

Sometimes you encounter a problem that just screams for using "parameterized" tests rather than copy/pasting the same method many times.   The test method is basically the same and the only thing that changes is the data passed in.  In this case, consider creating a test case that utilitizes the "Parameterized" class from JUnit.

I recently ran into a problem where our validation of an email address did not allow unicode characters.  The fix was fairly straight-forward, change the regular expression to allow those characters.  Next, it was time to test the change.  Rather than copy/paste separate methods for each set of data, I decided to learn about the Parameterized method.   Below is the result.  The data includes the expected result and the email address to be validated.

JUnit test class
package com.mycompany.client;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.mycompany.test.TestServiceUtil;

/**
 * Parameterized test case for validating email addresses against a regular expression.
 * We need to allow unicode characters in the userid portion of the email address, so 
 * these test cases where created to help validate the validateEmailAddress method
 * in the FieldValidationController class.
 * 
 * @author mmiller
 *
 */
@RunWith(Parameterized.class)
public class TestFieldValiationController {

    @Parameters(name = "{index}: {1} is valid email address = {0}")
    public static Iterable data() {
        return Arrays.asList(new Object[][] { 
         { true, "john@mycomp.com" },           { true,  "john123@mycomp.com" },
         { true, "j+._%20_-brown@mycomp.com" }, { true,  "123@mycomp.com" },
         { false, "john brown@mycomp.com" },    { false, "123@mycomp" },
         { false, "john^brown@mycomp.com" },    { true , "1john@mycomp.com" },
         { false, "john#brown@mycomp.com" },    { false, "john!brown@mycomp.com" },
         { false, "john()brown@mycomp.com" },   { false, "john=brown@mycomp.com" },
         { true,  "johñ.brown@mycomp.com" },    { false, "john.brown@mycomp.coñ" },
         { true,  "johú@mycomp.com" },          { true,  "johíáó@mycomp.com" }
        });
    }
  
    private boolean expected;
    private String emailAddress;

    public TestFieldValiationController(boolean expected, String emailAddress) {
        this.expected = expected;
        this.emailAddress = emailAddress;
        TestServiceUtil.getInstance();
    }

    @Test
    public void validateEmail() {
        assertEquals(expected, FieldValidationController.getInstance().validateEmailAddress(emailAddress));
    }
}

Hope this helps!

Monday, March 10, 2014

Creating a simple JAX-RS MessageBodyWriter

JAX-RS is really cool and with the help of JAXB a lot of response data types can be converted for you simply by adding annotating the data objects with JAXB annotations.  I am fairly new at JAXB but some simple cut/paste of annotations will take you a long way.

There maybe some types of data that you can't or won't annotate for the purposes of returning that data type from a JAX-RS resource method.   One simple example is returning either a boolean (primitive) or the wrapper Boolean class.   I read a question on StackOverflow where someone asked if they could return a boolean from a resource method and since I didn't know the answer, I decided to try it!  My version only returns XML, not JSON but you should get the idea.

I started with the Jersey User's Guide HelloWorld example and starting modifying from there.  I used the pom.xml and the only change was to uncomment a block to allow using JSON.

Main class 
This the main class from the Hello World example without any changes.

package com.example;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import java.io.IOException;
import java.net.URI;

/**
 * Main class.
 *
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/myapp/";

    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in com.example package
        final ResourceConfig rc = new ResourceConfig().packages("com.example");

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    /**
     * Main method.
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}

Resource class
I created a resource class that included a GET method to return a boolean and another GET method to return the wrapper Boolean class.  Notice the getBool() and getBoolean() methods return XML as the first option.

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public String getIt() {
        return "Got it!";
    }

    @GET
    @Path("/bool")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public boolean getBool() {
        return false;
    }

    @GET
    @Path("/Boolean")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public Boolean getBoolean() {
        return Boolean.TRUE;
    }
}


BooleanMessageBodyWriter class
Here's the interesting part, creating the MessageBodyWriter class to allow the resource method to return XML for the boolean or Boolean.

package com.example;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.WebApplicationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

@Provider
@Produces("application/xml")
public class BooleanMessageBodyWriter implements MessageBodyWriter {
 
    @Override
    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        System.out.println("isWriteable called...");
        return type == Boolean.class;
    }
 
    @Override
    public long getSize(Boolean myBool, Class type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }
 
    @Override
    public void writeTo(Boolean myBool,
                        Class type,
                        Type genericType,
                        Annotation[] annotations,
                        MediaType mediaType,
                        MultivaluedMap httpHeaders,
                        OutputStream entityStream)
                        throws IOException, WebApplicationException {
 
        StringBuilder sb = new StringBuilder();
        sb.append("").append(myBool.toString()).append("");
        DataOutputStream dos = new DataOutputStream(entityStream);
        dos.writeUTF(sb.toString());
    }
}

I  haven't used Maven before but the following targets are all you need to compile and run the project, after installing maven (of course!).
  • mvn compile - compiles the code
  • mvn exec:java - starts the Grizzly HttpServer and deploys the restful service.
Hope this helps!

Tuesday, January 14, 2014

Book Review: Professional Node.js Building JavaScript-Based Scalable Software

Overview
As a result of the recent explosion of JavaScript's popularity, partially led by Node.js, I decided to spend some time updating my JavaScript skills. I started reading a lot of articles and posts and then came across a recommended approach to learning Node on JavascriptIsSexy.com and decided to give it try.

Contents
The book is broken up into 6 parts(listed below), with a total of 25 chapters covering 350 pages, written by Pedro Teixeira.

  1. Introduction and Setup
  2. Node Core API basics
  3. Files, Processes, Streams and Networking
  4. Building and Debugging Modules and Applications
  5. Build Web Applications
  6. Connecting to Databases
The book is not an introduction to JavaScript, nor does it spend the first couple chapters attempting to ramp up readers on the JavaScript language, which I appreciated.  Readers should already have some basic JavaScript knowledge before reading this book.

Pros
  • Well written and easy to follow along with the code examples
  • The chapters covered the material without getting too long.  Easy enough to spend about 1/2 hour reading a chapter and working through the code examples for the chapter
  • The book got me excited about the possibilities available using Node.js and started me down a new path to help build my "full stack developer" skills.
Cons
  • The code examples were good, but I think it would help early in the book to point out where to find the Node API documentation, otherwise the reader is sometimes left wondering, "How did they know what methods are available, what to call and what to pass to that API?"
  • For all the positive impact NPM has had on Node.js, the coverage of NPM in the book seems a bit light, although that could just be lack of Node knowledge showing!
Conclusion
I was very happy with the book and would recommend it for anyone with some basic JavaScript skills looking to learn about Node.js.

I usually stick to Manning or O'Reilly books but when I started my quest for Node knowledge, neither of those publishers had books covering Node.  This has since changed and I may try one of those out as well.