Thursday, November 29, 2012

A very light Groovy based web application project template

You might have heard of the project Grails is a Groovy version of Ruby on Rails like framework that let you create web application much more easier with Dynamic scripting. Despite all that power Grails provided, it is not "light" if you look under the hood. I am not saying Grails is bad or anything. Grails is actually pretty cool to write web application with. However I found myself often want something even lighter and yet still want to prototype with Groovy. So here I will show you a maven-groovy-webapp project template that I use to get start any web application development. It's very simple, light, and yet very Groovy.

How to get started

Unzip maven-webapp-groovy.zip above and you should see these few files:

bash> cd maven-webapp-groovy
bash> find .
bash> ./pom.xml
bash> ./README.txt
bash> ./src
bash> ./src/main
bash> ./src/main/java
bash> ./src/main/java/deng
bash> ./src/main/java/deng/GroovyContextListener.java
bash> ./src/main/resources
bash> ./src/main/resources/log4j.properties
bash> ./src/main/webapp
bash> ./src/main/webapp/console.gt
bash> ./src/main/webapp/health.gt
bash> ./src/main/webapp/home.gt
bash> ./src/main/webapp/WEB-INF
bash> ./src/main/webapp/WEB-INF/classes
bash> ./src/main/webapp/WEB-INF/classes/.keep
bash> ./src/main/webapp/WEB-INF/groovy
bash> ./src/main/webapp/WEB-INF/groovy/console.groovy
bash> ./src/main/webapp/WEB-INF/groovy/health.groovy
bash> ./src/main/webapp/WEB-INF/groovy/home.groovy
bash> ./src/main/webapp/WEB-INF/groovy/init.groovy
bash> ./src/main/webapp/WEB-INF/groovy/destroy.groovy
bash> ./src/main/webapp/WEB-INF/web.xml

As you can see it's a maven based application, and I have configured tomcat plugin, so you may run it like this:

bash> mvn tomcat7:run
bash> open http://localhost:8080/maven-webapp-groovy/home.groovy

And ofcourse, with maven, running package phase will let you deploy it into any real application servers when ready.

bash> mvn package
bash> cp target/maven-webapp-groovy.war $APP_SERVER_HOME/autodeploy

What's in it

You should checkout the main config in web.xml file, and you'll see that there couple built-in Groovy servlets and a custom listener.

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

    <description>Groovy Web Application</description>
    <welcome-file-list>
        <welcome-file>home.groovy</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>GroovyServlet</servlet-name>
        <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GroovyServlet</servlet-name>
        <url-pattern>*.groovy</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>TemplateServlet</servlet-name>
        <servlet-class>groovy.servlet.TemplateServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TemplateServlet</servlet-name>
        <url-pattern>*.gt</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>deng.GroovyContextListener</listener-class>
    </listener>
    <context-param>  
       <param-name>initScripts</param-name>
       <param-value>/WEB-INF/groovy/init.groovy</param-value>
    </context-param>
    <context-param>    
       <param-name>destroyScripts</param-name>
       <param-value>/WEB-INF/groovy/destroy.groovy</param-value>
    </context-param>

</web-app>

I've chosen to use GroovyServlet as a controller (it comes with Groovy!), and this let you use any scripts inside /WEB-INF/groovy directory. That's it, no further setup. That's about the only requirement you need to get a Groovy webapp started! See console.groovy as example and how it works. It's a groovy version of this JVM console

Now you can use Groovy to process any logic and even generate the HTML output if you like, but I find it even more easier to use TemplateServlet. This allow Groovy template files to be serve as view. It's very much like JSP, but it uses Groovy instead! And we know Groovy syntax are much shorter to write! See console.gt as exmaple and how it works.

The GroovyContextListener is something I wrote, and it's optional. This allow you to run any scripts during the webapp startup or shutdown states. I've created an empty init.groovy and destroy.groovy placeholder. So now you have all the hooks you need to prototype just about any web application you need.

Simplicity wins

This setup is just plain Java Servlet with Groovy loaded. I often think the more simple you get, then less bug and faster you code. No heavy frameworks, no extra learning curve, (other than basic Servlet API and Groovy/Java skills ofcourse), and off you go.

Go have fun with this Groovy webapp template! And let me know if you have some cool prototypes to show off after playing with this. :)

Friday, November 16, 2012

Use cygpath with -p option for your Java CLASSPATH conversion

I just noticed that Cygwin's cygpath command supports -p option. This is a real gem when writing Java wrapper script that needs to covert CLASSPATH values. A simple script can demonstrate the purpose.


#!/usr/bin/env bash
# Author: Zemian Deng, Date: 2012-11-16_06:30:00
#
# run.sh - A simple Java wrapper script for Cygwin and Unix/Linux shell. We assume 
# this script is located in a subdiretory inside the application home directory.
# Example:
#   app/bin/run.sh
#   app/config/log4j.properties
#   app/lib/log4j.jar
# Usage:
#   bash> run.sh app.Hello
#
DIR=$(cd "$(dirname $0)/.." && pwd)
CP=${CP:="$DIR/config:$DIR/lib/*"}
if [[ "$OS" == Windows* ]]; then
 CP=$(cygpath -mp $CP)
fi
java -cp "$CP" "$@"

Saturday, November 3, 2012

What does UTF-8 with BOM mean?


Believe it or not, There is no such thing as Plain Text!

All files in a modern Operating Sytems (Windows, Linux, or MacOSX) are saved with an encoding scheme! They are encoded (a table mapping of what each byte means) in such way so that other programs can read it back and understand how to get information out. It happens that US/ASCII encoding is earliest and widely used that people think it's just "Plain Tex". But even ASCII is an encoding! It uses 7 bits in mapping all US characters in saving the bytes into file. Obviously you are free to use any kind of encoding (mapping) scheme to save any files, but if you want other programs to read it back easily, then sticking to some standard ones would help a lot. Without an agreed upon encoding, programs will not able to read files and be any useful!
The most useful and practical file encoding today is "UTF-8" because it support Unicode, and it's widely used in internet.

I discovered something odd when using Eclipse and Notepadd++. In Ecilpse, if we set default encoding with UTF-8, it would use normal UTF-8 without the Byte Order Mark (BOM). But in Notepad++, it appears to support UTF-8 wihtout BOM, but it won't recoginze it when first open. You can check this by going Menu > Encoding and see which one is selected. Notepad++ seems to only recognize UTF-8 wihtout BOM with ones it converted by it's own conversion utility. Perhaps it's a bug in notepad++.

So what is BOM? The byte order mark is useless for UTF-8. They only used for UTF-16 so they know which byte order is first. But UTF-8 will allow you to save these BOM for conversion purpose... they are ineffective in encoding the doc itself. So a "normal" UTF-8, it won't have BOM, but Windows would like to use them anyway. The Windows NOTEPAD would automatically save BOM in UTF-8!

So be-aware when viewing UTF-8 without BOM encoding files in Notepad++, as it can be deceiving at first glance.

Ref: