Java development 2.0: Gaelyk for Google App Engine

A Groovy-based framework makes rapid development on Google App Engine even faster

The introduction of the Google App Engine saw a wave of frameworks emerge to facilitate developing applications targeted for it. The Gaelyk framework, one such framework written in Groovy, eases development of lightweight applications that leverage a datastore. And the scalability you can achieve is impressive.

Andrew Glover, Author and developer

Andrew GloverAndrew Glover is a developer, author, speaker, and entrepreneur with a passion for behavior-driven development, Continuous Integration, and Agile software development. You can keep up with him at his blog.



15 December 2009

Also available in Chinese Russian Japanese Portuguese

This series explores aspects of technology that are shaping Java™ development now and in the future. The premise of Java development 2.0 is that development is happening at a more rapid pace, thanks to both a burst of innovation in the open source world and the commoditization of hardware. You can rent or borrow someone else's hardware platform to host your application (largely assembled from open source libraries, tools, and frameworks) at a fraction of the cost of acquiring and maintaining your own infrastructure.

About this series

The Java development landscape has changed radically since Java technology first emerged. Thanks to mature open source frameworks and reliable for-rent deployment infrastructures, it's now possible to assemble, test, run, and maintain Java applications quickly and inexpensively. In this series, Andrew Glover explores the spectrum of technologies and tools that make this new Java development paradigm possible.

The first series installment, "Hello Google App Engine," examined the notion of borrowing Google's infrastructure to host your Java application for free, but at some cost in terms of flexibility. In subsequent articles, you learned the differences between App Engine and Amazon's EC2. Last month's column ("REST up with CouchDB and Groovy's RESTClient") surveyed an up-and-coming alternative to relational databases: CouchDB. CouchDB's lack of a schema and its document-oriented nature might have seemed new to you, but you already saw another schemaless datastore in action with Google App Engine.

This article takes the series full circle, back to Google App Engine. The open source world has already jumped on the App Engine bandwagon, with frameworks starting to emerge that facilitate developing applications targeted for the platform. You'll see how an open source project called Gaelyk is making it even easier to build applications that leverage many of technologies the series has covered to this point.

Lightweight is the new rapid

Although Google's infrastructure is largely free to use (remember, it costs you money once you reach 500MB of storage and the bandwidth for serving about 5 million page views a month), it does come at a cost in terms of flexibility. Google's infrastructure supports Java technology, but not all core Java libraries and related open source libraries. The App Engine is a platform — you must develop to it. Unsurprisingly, though, open source innovations are helping to overcome what may be perceived as barriers to adoption of Google App Engine.

One such upstart project, dubbed Gaelyk, is a slick framework that facilitates the development of lightweight applications, written in Groovy, that properly leverage the Model-View-Controller (MVC) pattern. And through the magic of Groovy, Gaelyk throws in a few ease-of-use facilities on top of the App Engine's APIs. Moreover, you can use Gaelyk alongside the Google App Engine plug-in for Eclipse. Rapid development and deployment of Google App Engine applications couldn't get any easier.

Google persistence

Google App Engine's persistence implementation is largely shielded from you, but rest assured that it isn't a relational database. Yet you, the developer, can save, read, update, and delete persistence objects via Google's platform through normal Java Data Objects (JDO) code or even via Google's low-level persistence API.

"REST up with CouchDB and Groovy's RESTClient" leveraged a parking-ticketing system to demonstrate the nature of a document-oriented database. Following suit, in this article I'm going to create a Web application that enables the creation, update, and removal of parking tickets. The Google persistence architecture isn't a document-oriented one, but its schemaless nature permits a rather flexible model. Thus the Web application will try to model a parking ticket as closely as possible by capturing:

  • Officer's name
  • Date
  • Location
  • Offense
  • Any associated notes

I'll just leave the location as a generic text box, because someone can represent where an offense has occurred in a variety of ways — such as in the parking lot of Best Buy or at the corner of 18th St. and D St. In essence, I won't try to delineate a specific format, because it isn't necessarily germane to the domain anyway.

In order to get started, you need to have the Google App Engine plug-in for Eclipse installed (see "Hello Google App Engine" for instructions). You also need to download the Gaelyk JAR file from the project's Web site (see Resources). Remember where this download resides, because you'll need to move it into a specific directory shortly.

The Gaelyk framework relies on Groovy, so you also need the latest Groovy release: a simple JAR file, groovy-all-1.6.5.jar at the time of this writing (see Resources). Lastly, you need to create an application ID via the Google App Engine admin panel. (You can reuse the one you created in "Hello Google App Engine" if you like.)

Next, create a new Google Web Application Project within Eclipse, click the Next button, and fill out the appropriate information. Be sure to uncheck the Use Google Web Toolkit option, as I've done in Figure 1, because you don't need it:

Figure 1. Creating a Google Apps Project in Eclipse
Create a new Google Web Application Project within Eclipse dialog box

Click the Finish button, and you'll have yourself the beginnings of a code base.

Now copy both the Groovy and Gaelyk JARs into your newly created project's war/WEB-INF/lib directory, shown in Figure 2:

Figure 2. Gaelyk's required libraries
Picture of your newly created project's war/WEB-INF/lib directory with the Groovy and Gaelyk JARs copied in

In order to configure Gaelyk, you need to provide Google App Engine with some additional information by editing the WEB-INF/appengine-web.xml file. Place your application ID in the application section at the top of this file, and add the bit of XML shown in Listing 1:

Listing 1. Required updates to App Engine's configuration
<static-files>
 <exclude path="/WEB-INF/**.groovy" />
 <exclude path="**.gtpl" />
</static-files>

This addition prevents Google App Engine from serving up various files statically that you'll end up creating as a part of using Gaelyk. As you'll see, Gaelyk leverages a templating model. Thus, files ending in .gtpl will act like JavaServer Pages (JSPs) and will be processed via the framework rather than by App Engine.

Next, open up the web.xml file, also found in the WEB-INF directory. This is the standard Web application configuration file we've all come to love over the years. (You worked with this file when you first visited both App Engine and EC2.) This file needs to map various patterns to particular servlets, so make your file look like Listing 2:

Listing 2. Updated web.xml file
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
 <servlet>
  <servlet-name>GroovletServlet</servlet-name>
  <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>
 </servlet>
 <servlet>
  <servlet-name>TemplateServlet</servlet-name>
  <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>GroovletServlet</servlet-name>
  <url-pattern>*.groovy</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>TemplateServlet</servlet-name>
  <url-pattern>*.gtpl</url-pattern>
 </servlet-mapping>
 <welcome-file-list>
  <welcome-file>index.gtpl</welcome-file>
 </welcome-file-list>
</web-app>

Note that the web.xml file specifies that the welcome file be index.gtpl; thus, rename the index.html file that the Eclipse plug-in generated for you to index.gtpl. (Just select the file and hit F2, if you are on Windows®.)

With the proper libraries in place and both XML files configured correctly, you can verify things are working by editing the index.gtpl file to match the contents of Listing 3:

Listing 3. A simple GTPL file
<html>
 <head><title>A Simple GTPL</title></head>
  <body>
   <b><% print "Hello Gaelyk!".replace(" ", " from ") %></b>
   <p>
   <ol>
    <% def wrd = "Groovy"
       wrd.each{ letter ->
    %>
    <li><%= letter %></li>
    <% } %>
   </ol>
   </p>
  </body>
</html>

As you can see, GTPL files (or Gaelyk/Groovy templates) in Gaelyk are just like JSPs: you can add behavior in scriptlets (in this case, the behavior is Groovy). Note that you can use closures and reference variables later too.

Save your index.gtpl file and then select the project's base directory in Eclipse, right-click, select Run As, and select the Web Application option that contains a blue G logo, as shown in Figure 3:

Figure 3. Running as a Google Web application
Screenshot of selecting the Web Application option that contains a blue G logo

By default, this launcher starts a local instance of Jetty on port 8080. If you'd like to change ports, select the Run Configurations option and configure the port via the options panel provided by the plug-in.

Now that a local instance of your Gaelyk Web application is running, open a Web browser and go to http://localhost:8080. The output of your lovely index.gtpl should look like Figure 4:

Figure 4. Hello world!
Screenshot of output of index.gtpl at http://localhost:8080

That was easy, wasn't it?


Easy persistence

The ticketing system is simple. It' offers a Web form for creating tickets and a list functionality to view, delete, and edit tickets. I'll start things off by creating a simple HTML form via a Gaelyk template, and I'll call it createticket.gtpl. This form, shown in Figure 5, tries to capture relevant data associated with an individual parking ticket:

Figure 5. A simple ticket form
Screenshot of a blank simple ticket form

The form will submit to a groovlet; accordingly, create a groovy folder inside the WEB-INF directory in your project. This is where you'll place your groovlets. (You did this in "Hello Google App Engine" too.) The create-ticket form will submit to a createticket.groovy file. Create this file in the newly created groovy directory.

You can certainly use JDO and Java Persistence API (JPA) code in Gaelyk, but there's another handy way to interface with the underlying datastore: by using Google's Entity object. The Gaelyk team has enhanced the Entity object via some Groovy magic to make working with persistent objects amazingly simple.

In this case, I'd like to capture the form elements submitted via the createticket.gtpl page and create a new ticket in the system. By using the Entity class, I don't need to define a POJO-like object to represent a ticket (as I did in "Hello Google App Engine" when I created a Triathlon JDO object). I can simply model a ticket in a Groovy fashion and save it almost as effortlessly.

Consequently, I can grab the parameters submitted by the form via Gaelyk's handy params object (which, by the way, Grails also offers) and create an Entity instance, as shown in Listing 4:

Listing 4. Creating an Entity
def formatter = new SimpleDateFormat("MM/dd/yyyy")
def offensedate = formatter.parse("${params.of_month}/${params.of_day}/${params.of_year}")

def ticket = new Entity("ticket")
ticket.officer = params.officer
ticket.license = params.plate
ticket.issuseDate = offensedate
ticket.location = params.location
ticket.notes = params.notes
ticket.offense = params.offense

Note that the ticket variable is an instance of Entity. The "ticket" String represents the kind of entity this is. This'll become handy in searching for tickets. Next, I automagically assign property values to the Entity instance associated with tickets. Now ticket.officer represents the value of the officer parameter submitted via the Web page form. Because the form contains three fields for date, I also create a date instance using a SimpleDateFormat and set that value to issueDate.

At this point, I've got an object that represents a ticket. All I need to do now is save it with:

ticket.save()

Now that I've persisted a ticket, I'll forward users to a page where they can view the ticket. That's easy too. I simply forward to a view-ticket Groovlet (for processing):

redirect "viewticket.groovy?id=${ticket.key.id}"

As you can see, I've created a parameter dubbed id and set it to the key of the saved ticket instance, which Google App Engine generated. Accordingly, the create-ticket Groovlet is terse yet highly functional — all of it facilitated by Gaelyk.


Easy views

In the preceding example, after I created the ticket instance, I proceeded to redirect the request to another Groovlet — one that facilitates viewing a ticket. In this Groovlet, I've coded a Google App Engine read, so to speak. The id that was passed along is then used to find the newly created instance. In this case, I'm using Google's KeyFactory, which is used to create an instance of Google's Key object. The Key then is used to find the corresponding ticket instance via the datastoreService, which Gaelyk has automatically added to the binding of any Groovlet instance within the framework, as you can seeing Listing 5:

Listing 5. Viewing an Entity
import com.google.appengine.api.datastore.KeyFactory

if (params["id"]) {
 def id = Long.parseLong(params["id"])
 try {
   def key = KeyFactory.createKey("ticket", id)
   def ticket = datastoreService.get(key)

   request.setAttribute "ticket", ticket

   forward "viewticket.gtpl"

   } catch (Throwable t) {
    //forward to some error page...
   }
} else {
 forward "index.gtpl"
}

Once the corresponding ticket is found, the ticket is placed into the HTTP request object (which is already present in a Groovlet) and then processing is forwarded to the viewticket.gtpl page. Just like any other JSP in a Web application, this Web page displays the corresponding attributes associated with the passed-in ticket.

As you can see in Listing 6, Gaelyk supports includes. That is, in your .gtpl files, you can include other files, just as you can in normal JSPs. Likewise, all .gtpl files have an instance of the HTTP Request object handy (via the request variable).

Listing 6. Viewing a single Entity GTPL
<% include "/WEB-INF/includes/header.gtpl" %>

<% def ticket = request.getAttribute("ticket") %>

<div class="info">
 <h2>Parking Ticket</h2>
 </div>

<table>
<tr>
	<th>Issuing Officer</th>
	<th>Vehicle Plate</th>
	<th>Date</th>
	<th>Offense</th>
	<th>Location</th>
	<th>Notes</th>
  </tr>
 <tr>
	<td>${ticket.officer} </td>
	<td>${ticket.license}</td>
	<td>${ticket.issuseDate}</td>
	<td>${ticket.offense}</td>
	<td>${ticket.location}</td>
	<td>${ticket.notes}</td>
  </tr>
 </table>

<% include "/WEB-INF/includes/footer.gtpl" %>

As you can probably see by this point, Gaelyk makes building lightweight Web applications on Google App Engine a breeze. And working with the App Engine's persistence store couldn't be easier. The low-level API you use when working with Entity objects does take a bit of getting used to. Queries require some thinking (kind of like querying with CouchDB, in a way). For instance, viewing a list of created tickets requires some code like Listing 7:

Listing 7. Viewing a collection of Entitys
import com.google.appengine.api.datastore.Query
import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit

try {
 def query = new Query("ticket")
 query.addSort("issuseDate", Query.SortDirection.DESCENDING)
 def preparedQuery = datastoreService.prepare(query)
 def tickets = preparedQuery.asList( withLimit(10) )

 request.setAttribute "tickets", tickets
forward "index.gtpl"
} catch (Throwable t) {
 forward "index.gtpl"
}

Listing 7 leverages App Engine's Query object. As you can see, you can add sort-like features to queries and even limit how many results are returned. No SQL is used, but rest assured that data is being stored and can be retrieved, albeit just a bit differently.

Just as in "Hello Google App Engine," deployment into the cloud is a breeze. Via the plug-in, simply click the Deploy App Engine Project and let Google take it from there. In fact, you can download the code for this article and do just that. The code will fill in some gaps that I didn't have space to cover in a single article. For example, I've implemented removing tickets, and the user interaction with the ticketing system is slightly enhanced, so you'll see a bit more of Gaelyk in action.


Fast development made easy

The cloud and schemaless datastores, bolstered by open source innovations, are certainly part of the future of Java development. Both have a low barrier to adoption; in this article's example, both the hardware and the software are completely free. And once Google does start to charge you money, you're bound to be making your own — 5 million hits a month is a tremendous amount of traffic. The Gaelyk framework brings an even faster pace to Web development. Java development just keeps getting better and better, don't you think?


Download

DescriptionNameSize
Source code for this article's examplesj-javadev2-6.zip8.3MB

Resources

Learn

  • Gaelyk: Learn more about this lightweight Groovy toolkit for Google App Engine for Java.
  • Google App Engine: Visit home base for Google's App Engine.
  • "Java development 2.0: Hello Google App Engine" (Andrew Glover, developerWorks, August 2009): Understand Java development 2.0 and how you can bring its concepts to fruition quickly with Google's App Engine for Java.
  • Practically Groovy (Andrew Glover and Scott Davis, developerWorks): This series explores the practical uses of Groovy, helping you learn when and how to apply them successfully.
  • Cloud Computing: Visit IBM® Cloud Computing Central for a wealth of cloud resources.
  • Browse the technology bookstore for books on these and other technical topics.
  • developerWorks Java technology zone: Find hundreds of articles about every aspect of Java programming.

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Cloud computing
ArticleID=454209
ArticleTitle=Java development 2.0: Gaelyk for Google App Engine
publish-date=12152009