Java development 2.0: Hello Google App Engine

Quick Web application development leveraging Groovy, Eclipse, and JDO

Open source solutions and borrowed infrastructures are changing the character of Java™ development, letting you deliver better software quickly and at a low cost. Andrew Glover, coining the term Java development 2.0 to encapsulate the cumulative force of these phenomena, launches a new series on some of the relevant tools and technologies. This first installment heralds the arrival of Java development 2.0 and explains how you can bring its concepts to fruition quickly with Google's App Engine for Java.

Share:

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.



18 August 2009

Also available in Chinese Russian Japanese Vietnamese Portuguese

The Java universe is a rich ecosystem with a widespread cast of developers, businesses, and — most important — applications, many of which have been maturing for well over a decade. The worldwide Java community has heavily invested money, time, and brain power in the platform, and these contributions have yielded a cornucopia of successful open source and commercial tools, frameworks, and indeed, solutions.

These myriad investments in the Java platform have subtly altered how Java development is done. Two key trends are rapidly changing its character:

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.

  • Fully capitalizing on open source tools and frameworks for building applications top to bottom
  • Renting (or borrowing) the application infrastructures required at all levels for managing the software life cycle, including running the applications themselves

Neither aspect of what I call Java development 2.0 is new or revolutionary, but the enabling technologies have matured to the point where it's now possible, as never before in Java technology's history, to assemble better applications quickly and cheaply — certainly one of the overriding desires of businesses across the globe.

This article launches a new series that will explore Java development 2.0 in depth. You'll learn about building and deploying Web applications with Amazon's EC2, using Google's App Engine, leveraging CouchDB (which is being called the database for the Web), and other tools and technologies that provide the building blocks for assembling, testing, and deploying applications in short order and for less money than was possible until now.

First stop: the Google App Engine for Java (see Resources). I'll introduce you to the platform via the time-honored "Hello World" methodology, then show you how to create a working Web application using Groovy, Java Data Objects (JDO), and the Eclipse plug-in for Google App Engine. First, though, a quick overview of the business value of Java development 2.0 is in order.

The quick and the cheap

The words quick and cheap haven't often been associated with Java development. In fact, they often conjure up impressions of less serious software development — the purview of small companies with few resources. The truth of the matter, however, is that IT is a cost center for many companies (large and small), which motivates them to keep IT costs low while extracting as much value as possible.

That's where Java development 2.0 comes into play. By leveraging open source tools, frameworks, and even solutions, companies can assemble software applications quickly because they themselves don't have to write as much code. When I first started developing with Java technology more than 10 years ago, the scope of tools and frameworks available to developers was much smaller. Those few tools were not freely available either. You had to buy an IDE, a database, an object-relational mapping (ORM) framework (heck, you might have had to buy the driver required to communicate with your database), and of course, the machines to deploy your application on. Now? Everything I just listed (and more) is freely available and of high quality.

What's more, by borrowing infrastructures (such as those offered by Amazon's EC2 or Google App Engine), you can deploy applications quite cheaply (compared to purchasing the required infrastructure outright).

To build, buy, or borrow: That's the new question

Many businesses have an inventory of hardware for running applications such as databases, application servers, change-management systems, and defect-tracking tools. Yet, in this day and age, this inventory can be easily jettisoned in favor of using the same software packages as a service running on someone else's infrastructure.

The entire stack of applications a team might use to manage a development process can be borrowed — that is, rented for a small fee — freeing a company from having to invest in the hardware to run them. For example, rather than purchasing a machine to run a change-management system (such as Subversion or Git, which are both open source and freely available), a team can use a shared change-management service such as GitHub. The company behind GitHub incurs the cost of hardware assets and charges a nominal fee (usually monthly per user) for other organizations to use Git. This same principle of renting software as a service from other providers can be leveraged for defect tracking, test-case management, and requirements management (via Hosted JIRA or Pivotal Tracker, for example).

The same can be said for the underlying hardware assets that other software platforms (usually custom in nature) run on. A business can jettison the underlying hardware for a particular Web application in favor of running the application on hardware provided by Amazon, Google, or other players in the space. These companies offer the ability to rent hardware in varying degrees, which can literally host an application. What's more, these companies manage scalability, backups, and even security. Think about it for a second: Amazon and Google figured out these concerns (and more) long ago and are better at dealing with and innovating around the aspects of efficiently running software platforms. (It's true. Face it.)

By using Google's App Engine, for example, an IT company can lower the overall cost of purchasing an infrastructure to run needed applications. And it can deploy those applications more quickly because the myriad cross-cutting concerns associated with application deployment and management are already taken into account and thus provided for (and most likely in a superior manner).

Quick and cheap no longer mean low quality. On the contrary, Java development 2.0 is a tactical approach that already assumes a solid process that stresses quality.


A simple day with Google's App Engine

The Google App Engine is a veritable platform for building and deploying Java (and Python) Web applications on Google's expansive infrastructure. It requires no licensing fees (unless, of course, some software library you choose to leverage on the infrastructure requires a license) and no upfront costs for bandwidth or space. The App Engine infrastructure is completely free until you reach a threshold of usage — 500MB of storage and, to quote Google, "enough CPU and bandwidth for about 5 million page views a month." Suffice it to say, once you reach a point where Google starts billing you, your Web application has clearly generated significant traffic (and therefore interest).

Getting up and running on the App Engine couldn't be any easier. Google even provides an Eclipse plug-in that handles just about everything for you. And the plug-in includes the essential components of a "Hello World" servlet application that helps you get started with the platform. In his recent introductory article on developerWorks ("Google App Engine for Java, Part 1: Rev it up!") Rick Hightower takes you through deploying the Hello World application (screenshots included). If you haven't already worked through Rick's article, follow these steps:

Versioning

App Engine deployments can be versioned — that is, you can assign a string pattern (which can signify a version) to a deployment. This is helpful when you begin to have multiple releases. Via URLs and Google's dashboard, you can delineate which version is the "live" one and which ones aren't (although any versioned deployment is accessible via a URL, provided you don't remove it first). Accordingly, any time you want to deploy a new version of your project to Google's infrastructure, you must give that deployment a valid version. The string pattern can't include periods (1.1 doesn't work, but 1-1 does). You can assign versions in the appengine-web.xml file found in the war/WEB-INF directory already generated for you when you created a new project. To deploy your very first project, you needn't deal with versions (yet) because Google specifies an initial version of 1 in the generated appengine-web.xml file.

  1. Create a Google App Engine account (it's free) by clicking the Sign up link under Getting Started on http://code.google.com/appengine/.
  2. Download the Google App Engine plug-in for Eclipse from http://code.google.com/appengine/downloads.html and install it.
  3. Create a new project by clicking the New Web Application Project button in Eclipse; in the resulting dialog, uncheck the Use Google Web Toolkit option. Name the project and the corresponding package whatever you'd like.
  4. Select your project in the hierarchy and click the Deploy App Engine Project button.
  5. Enter your credentials (the ones you used when you created an App Engine account in Step 1).
  6. Associate your local project with the application ID you created when you initially created an App Engine account. (You can have up to 10 IDs.)
  7. Click the Deploy button. You'll see a lot of text fly by on the Eclipse console (the plug-in is doing a lot behind the scenes including enhancing any required classes that leverage Google's impressive data-storage service). Once the noise settles down (and everything worked correctly), you should see a message that ends with "Deployment completed successfully."
  8. Go to your App Engine account page at Google and find the Versions link on the Google dashboard. There you'll see your deployed version and its corresponding URL. Click the URL and then the link to the generated servlet to view the prosaic but oh so gratifying "Hello, world" printed in plain text.

Fewer lines of code with Groovlets

You've successfully deployed your first Google App Engine application and you didn't write a line of code. In truth, if you plan to leverage the App Engine, you'll end up writing some code — but remember, a lot of code is out there that you can reuse to make your job easier. That reusable code could be the services that Google provides (such as its data-store or Google account services) or open source libraries that have been ported to work on Google's infrastructure. Reusing other people's code means you often end up writing less code — and less code in all likelihood means fewer defects.

One of my favorite open source libraries (and indeed platforms) that almost always yields fewer lines of code to produce working applications is Groovy (see Resources). The Groovy team recently released versions of the platform that work on the App Engine, letting you leverage Groovlets instead of servlets to knock out a working application in short order. Groovlets are simple Groovy scripts that act like servlets. Because you already have a servlet that prints "Hello, world," I'll show you how easy it is to do the same thing with a Groovlet (and you'll see just how many fewer lines of code Groovy enables).

Deploying a Groovlet on the App Engine with the Eclipse plug-in takes a few easy steps:

  1. Download the latest version of Groovy (at the time of this article, 1.6.3) from http://groovy.codehaus.org/Download.
  2. Find the groovy-all-1.6.3.jar and place it into your App Engine project's war/WEB-INF/lib directory. By the way, in this directory, you can place any library your application requires (with some caveats that I'll cover shortly).
  3. Add the phrases in Listing 1 (which map Groovlets to specialized requests) to the web.xml file found in the war/WEB-INF directory:
    Listing 1. Updating the web.xml file to support Groovlets
    <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>
  4. Add a groovy directory to your WEB-INF directory; this is where you'll store your Groovlets. In the groovy directory, create a new file called helloworld.groovy. In that new file, type println "Hello, Groovy baby!"
  5. Update the version of your application — say to 1-1 — and redeploy. Find the corresponding URL via the Google dashboard and then surf to /helloworld.groovy in your browser and enjoy the splendor of a hip message printed from Groovy on Google's infrastructure.

That was easy, right? All you had to do was add the Groovy JAR, update the web.xml file, create a new groovy directory, write a Groovlet, and deploy it. Did you also notice how the Groovlet did the same thing as the default servlet the plug-in generated but in one line of code? Which would you rather have to write and maintain: a big class or a small one that does the same thing?


Groovy + Java = working application. Quickly.

Now I'll show you how using Groovy along with Google's App Engine can yield a working application in short order. I'll use a simple HTML page, a Groovlet, and a JDO-enhanced Java class to persist an event (in this case, a triathlon). I'll keep it simple for now, but you'll see that this application can grow to include other features, and in future articles in this series you'll implement them (using different infrastructures and technologies, of course).

Rapid JDO

The Google App Engine offers the ability to persist data using JDO, which is a Java standard for persistence (see Resources). For most Java developers, persisting data usually implies saving information to a relational database; however, in Google's case, the underlying storage mechanism is its proprietary Big Table, which isn't relational. That being said, it doesn't really matter: the details of how Google persists specific attributes are largely hidden from you. Suffice it to say, you can use normal Java objects (or Groovy objects, for that matter) to build an application that can store information as you would in any other application. It's just that in Google's case, you must use JDO. (Hibernate, arguably the most popular ORM framework for Java, doesn't work on the App Engine.)

JDO is quite simple. You create POJOs — plain old Java objects (which can have relationships to other Java objects) — that you declare as persistence-capable via the class-level @PersistenceCapable annotation. You specify which properties of the object are to be persisted via @Persistent annotations. For example, I'd like to store triathlon events (for now, I'll focus on the event and not the various results related to a triathlon) — that is, an event has a name (the name of the triathlon), perhaps a description (what type of triathlon), and a date. So far, my JDO looks like Listing 2:

Listing 2. A simple triathlon event JDO
import java.util.Date;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.IdentityType;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

}

Data persistence, regardless of the underlying mechanism (that is, relational or Google's Big Table) still requires the notion of a key : a way to guarantee uniqueness of various aspects of data to avoid data clashes. For example, in the case of a triathlon the key could be the name of the triathlon. If two triathlons have the same name, then the key could be a combination of the name and the date. Regardless of how you choose to represent a key with Google's App Engine and JDO, you must specify a key in your JDO object via the @PrimaryKey annotation. You can also choose strategies for how a key is generated — either by you or by the Google infrastructure. I'll defer to Google and make it simple: my triathlon object's key is represented as a normal Java Long object, and I'll let Google pick the actual value by specifying a value strategy. Listing 3 adds the primary key:

Listing 3. Adding a primary key to the triathlon JDO
import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.IdentityType;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Long id;

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

 public Triathlon(Date date, String name, String description) {
  super();
  this.date = date;
  this.name = name;
  this.description = description;
 }

 //...setters and getters left out

 public String toString() {
  return ReflectionToStringBuilder.toString(this);
 }

 public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(this);
 }

 public boolean equals(Object obj) {
  return EqualsBuilder.reflectionEquals(this, obj);
 }
}

As you can see in Listing 3, my triathlon JDO now has a key managed by the Google infrastructure, and I've added a few standard methods (toString, hashCode, and equals) that help tremendously for debugging, logging, and of course, proper functionality. Rather than write them myself, I'm using the Apache commons-lang library (see Resources). I also added a constructor that'll make creating fully initialized objects a lot easier as compared to calling a lot of setter methods.

I've kept my JDO simple on purpose, but as you can see, there isn't much to it (that is, I've left out any relationships and omitted getters and setters for brevity's sake). You simply model your domain and then decorate the model with a few annotations, and Google takes care of the rest.

With an object defined as persistence-capable, there's one last step. To interact with the underlying data-store, you need to work with a PersistenceManager, which is a JDO standard class that does what its name implies: saves, updates, retrieves, and removes objects from an underlying data store (much like Hibernate's Session object). This class is created via a factory (PersistenceManagerFactory), which is rather heavyweight; thus, Google recommends creating a singleton object that manages a single instance of the factory (which will then return a proper PersistenceManager when you need it). Accordingly, I can define a simple singleton object for returning an instance of a PersistenceManager, as shown in Listing 4:

Listing 4. A simple singleton for returning a PersistenceManager instance
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public class PersistenceMgr {

 private static final PersistenceManagerFactory instance =
   JDOHelper.getPersistenceManagerFactory("transactions-optional");

 private PersistenceMgr() {}

 public static PersistenceManager manufacture() {
  return instance.getPersistenceManager();
 }
}

As you can see, my PersistenceMgr is quite simple. The one method, manufacture, returns a PersistenceManager instance from a single instance of a PersistenceManagerFactory. You'll also notice that there is no Google-specific code in Listing 4 or any other listing leveraging JDO — all references are to standard JDO classes and interfaces.

The two newly defined Java objects reside in my project's src directory, and I added the commons-lang library to the war/WEB-INF/lib directory.

With a simple triathlon JDO POJO defined and a PersistenceMgr object handy, I'm good to go. All I need now is a way to capture triathlon information.


Capturing data via a Web interface

Most Web applications follow the same pattern: capture information via HTML forms and submit them to a server-side resource for handling. Sure, a lot of spice is mixed in here and there, but the pattern remains the same regardless of the underlying technology or infrastructure. The Google App Engine is no different — I've already coded the server-side resource to handle saving triathlon data. All that's left is a way to capture the information — a form — and a way to tie the server side and the form together. In Model-View-Controller (MVC) parlance, I need a controller, which is often a servlet; I'll leverage a Groovlet instead because I'd rather write less code.

My HTML form is simple: all I've done is created an HTML page that leverages some simple Cascading Style Sheets (CSS) code to make the form, shown in Figure 1, look more like Web 2.0 than HTML pages circa 1998:

Figure 1. A simple HTML form
A simple HTML form

As you can see in Figure 1, the form captures a name, description, and a date. The date, however, isn't that simple — it really is three attributes of a date.

Groovlet quickly

Groovlets make controller coding a snap: they require less code and provide needed objects automatically. In a Groovlet, you have implicit access to the HTML request and response via the request and response objects, respectively. In my Groovlet, I can grab all the attributes of the submitted HTML form via the request.getParameter("name") call, as shown in Listing 5:

Listing 5. Groovlets in action
def triname = request.getParameter("tri_name")
def tridesc = request.getParameter("tri_description")
def month = request.getParameter("tri_month")
def day = request.getParameter("tri_day")
def year = request.getParameter("tri_year")

The JDO I coded earlier leverages a Java Date object; however, in Listing 5, I'm dealing with three distinct attributes of Date. So I need a DateFormat object to convert the month, day, year combination into a normal Java Date, as shown in Listing 6:

Listing 6. Date formatting in action
def formatter = new SimpleDateFormat("MM/dd/yyyy")
def tridate = formatter.parse("${month}/${day}/${year}")

Lastly, with all the parameters obtained from a submitted HTML form, I can persist them in Listing 7 to Google's infrastructure via my JDO and the PersistenceMgr object from Listing 4:

Listing 7. JDO to persistence easily
def triathlon = new Triathlon(tridate, triname, tridesc)
def mgr = PersistenceMgr.manufacture()

try {
 mgr.makePersistent(triathlon)
} finally {
 mgr.close()
}

That's it! Of course, as more pages are added to my simple application (such as capturing the results of a particular triathlon), I'd then probably forward or redirect to another form, which would then capture additional information, much like a wizard. Nevertheless, in a few short code snippets, I quickly put together a simple Web application that persists data to Google's infrastructure via JDO (coded in normal Java) and a Groovlet (coded in Groovy, of course). Deploying the application is as easy as specifying a version in the appengine-web.xml file and clicking the Deploy button.

Although this one-form Web application for capturing triathlon events didn't boil the ocean, so to speak, I did just deploy to an amorphous, omnipresent environment. I didn't have to fire up a Web container or even specify where to deploy the application. (Is it residing in California, my hard drive, or the moon?) The beauty is that it doesn't matter — Google has taken care of it. All of it. What's more, it's a safe bet that Google has figured out how to scale globally so that someone viewing the application in India has the same experience as someone in say, Argentina.

With all that said, you do need to keep a few things in mind. Google's infrastructure supports Java technology, but not everything; if you remember when J2ME came out years ago, App Engine's limitations are somewhat similar in nature. That is, not all core Java libraries and related open source libraries are supported. As I mentioned, Hibernate can't be used (mainly because with the App Engine you don't have a relational database). I also had some challenges using some open source libraries that embedded base64 encoding (Google requires you use its URL Fetch service instead). The App Engine is a platform — you must develop to it and, for now, that can be a one-way street.


The future is already here

Alan Kay, one of the fathers of object-oriented programming, is quoted as having said, "The best way to predict the future is to invent it." I agree with Alan Kay. Regardless of what other people are suggesting the future holds for Java technology, I think the future is already here.

As you saw in this article, the Google App Engine is a platform for the future — provided you play in its sandbox. (Keep in mind that I covered only a few grains of sand in that sandbox; the App Engine has a lot of features). If you want more flexibility (that is, you want a relational database and can't live without Hibernate) but also like the idea of borrowing someone else's scalable infrastructure, alternatives are available. Amazon's EC2 is literally a virtual server on an amorphous infrastructure that you can also summon on-demand. You'll check it out in next month's Java development 2.0 installment.

Resources

Learn

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, Web development
ArticleID=421586
ArticleTitle=Java development 2.0: Hello Google App Engine
publish-date=08182009