Thursday, June 26, 2008

Rapid Web Application Prototypes with Maven and Groovy

Utilizing both Maven and Groovy you can rapidly prototype web apps, and in this blog I'll walk you through exactly how to do that. First we are going to create a simple Maven web app project using the Maven Web App Archetype. If you don't have Maven installed already, go ahead and install it. Now let's create a directory called sandbox, and cd into that directory. Now let's create our project by issuing the following command:

mvn archetype:generate

When prompted to choose a number enter 18 (The Java web application archetype) and hit enter. Next you will be prompted for the groupId, enter com.sample and hit enter, for the artifactId enter sample and hit enter, for the version enter 1.0 and hit enter, and for the package name enter com.sample and hit enter. Confirm you project by entering "Y" and hitting enter. Once finsihed you will have a maven project ready to go for deployment. You should see a sample diretory that was created in /sandbox with a pom.xml file. The pom.xml file is what we will look at next.

Next we need to add the dependency for Groovy to our pom, as well as the Maven Groovy Plugin. We do this by adding the following inside the <build> element in the parent pom:


<plugins>
<plugin>
<groupId>org.codehaus.mojo.groovy</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
Now that we have the Groovy Plugin added, lets add the Groovy dependency to the pom as well by adding it inside the <dependencies> element of the pom:

<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.5.6</version>
</dependency>
Ok, let's save all that and make sure we can build everything. From /sandbox/sample issue the following command:

mvn clean install

You should now have a successful build, and you could actually deploy the war that gets created (in /sandbox/sample/target you will have sample.war) to an application server such as JBoss. Ok, lets get onto the cool stuff. Groovy has a concept that lets you write normal Java servlets in Groovy, called Groovlets. Groovlets are really easy to work with and have some nice features like implicit variables (e.g. request and response which are bound to the ServletRequest and ServletResponse). So what we are going to do is configure our webapp so that it can handle Groovlets and then create our first Groovlet. We are first going to edit our web.xml which is located at /sandbox/sample/src/main/webapp/WEB-INF/, go ahead an open that up and add the following between the <web-app> elements:

<servlet>
<servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GroovyTemplate</servlet-name>
<servlet-class>groovy.servlet.TemplateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GroovyServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GroovyTemplate</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
This configures your webapp to compile your .groovy files to bytecode and execute your script when called. Next we need to create our Groovlet and then we are done. So, in /sandbox/sample/src/main/webapp create a file called Sample.groovy. We are going to create a simple Groovlet that accepts an HTTP GET request and has a parameter called username. We will process the request and just print out the response. So, go ahead and open up the Sample.groovy file you opened and add the following:

def username = request.getParameter("username")
println "Hello ${username}"
That's it. Rember that the request variable is implicit, meaning it's already bound to the ServletRequest and ready for use. Now we can compile our war, and deploy it to your favorite application server and you are ready to roll. Once deployed navigate to http://localhost:8080/sample/Sample.groovy?username=Chad in your web browser and you should see the print out "Hello Chad".

This is a really nice way to rapidly prototype webapps. I first started looking into this when I needed a servlet that could access the file system and return XML based off my lookup. Obiously using Groovy's nice features that have been added to the JDK for working with Files, and the MarkupBuilder, this task was trivial. Give it a spin and let me know what you think.

Monday, June 9, 2008

Deploying Jersey REST services to Weblogic

I recently had some trouble deploying a REST service using Jersey to Weblogic, specifically Weblogic 9.2. This had me stumped for quite a while as I could deploy my war to JBoss and Tomcat and it worked fine. Finally with an assist from the mailing list I was able to get past the problem and get the war to deploy. As Paul noted, the problem was that the default class scanning technique is not portable across servlet implmentations, so I needed to add the following to my web.xml (after the <servlet-class> element):


<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*';' separated package names*</param-value>
</init-param>


This tells Jersey to use the package scanning instead of the class path scanning. Now all you have to do is insert your package names in the last param value (replace the *';' with your package name(s) seperated by ';').

For more detail on this issue see the issue that was filed with Jersey here.