EC2 Continuous Deployment: Building the software

Note: This is the second article in the series on continuous deployment. If you want to start with the overview, go here.

The app we’ll deploy will just be a simple “Hello World” application, written using Lift, a very nice Scala web framework. I will not go into any Scala or Lift specifics in this article, but will  show how to build it.

Prerequisites

You need to have JDK 1.5+ and a recent version of Maven  installed.

Generating the example app

Run the following to download all dependencies and generate a simple “Hello world” Lift app.  Just press enter to any questions that you may have to answer.

$ mvn archetype:generate -U \
  -DarchetypeGroupId=net.liftweb \
  -DarchetypeArtifactId=lift-archetype-blank \
  -DarchetypeVersion=1.0 \
  -DremoteRepositories=http://scala-tools.org/repo-releases \
  -DgroupId=demo.helloworld \
  -DartifactId=helloworld \
  -Dversion=1.0

You should now have a project created in the directory helloworld. Verify that everything works:

$ cd helloworld
$ mvn jetty:run

When the last step has finished (it will take a while :-)), point your browser to http://localhost:8080/ and see a nice welcome message!

Building with Gradle

Maven seems to be the build tool of choice for many Java projects. While the automatic dependency management is nice, I’ve never liked the XML based pom files and the fact that every custom action must be defined in a plugin. This means that you’ll need to bring out the somewhat heavy Java machinery to create custom functionality, something which I think ought to be easier.

Lately it seems (at least to me :-)) a new breed of tools are appearing: Based on some dynamically typed language (Python,  Ruby etc), custom DSL’s are created to ease the task at hand. At least in theory, this has the potential to give the best of both worlds: A well thought out framework that does most of the job and a full scripting language to perform those tasks that inevitably  pops out when you try to automate your entire build process. Gradle is one such tool. It is a tool for building (mainly Java based) software and is based on the Groovy language. Later, we’ll look at Chef, a Ruby based tool for managing deployments.

While Gradle is a new build system that’s still a little rough around the edges, it shows promise and doesn’t require XML for configuration. yeah!

Unfortunately, Gradle doesn’t come with a Scala plugin out of the box so we’ll need to build Gradle from source in order to apply this patch

$ svn co http://svn.codehaus.org/gradle/gradle-core/tags/REL-0.5.2/
$ cd REL-0.5.2/
$ curl -O http://jira.codehaus.org/secure/attachment/37898/scala-plugin-04Nov2008.patch
$ patch  -p0 <scala-plugin-04Nov2008.patch
$ echo >> src/toplevel/plugin.properties && echo "scala=org.gradle.api.plugins.scala.ScalaPlugin" >> src/toplevel/plugin.properties
$ ./gradlew -Pgradle_installDir=/Users/jeppe/gradle -Pgradle_installDirName=gradle-0.5.2 clean install

This should build and install Gradle into the specified folder. Note that the patch fails to apply changes to plugin.properties, hence the manual change above.

Building a Lift webapp with Gradle

As opposed to Ant, Gradle has a lof of stuff configured by convention, which means a build file can be quite easy to understand and still provide a lot of functionality. The following simple build.gradle file can be used to compile, unit test, package and run the Lift app using Gradle. Place the file in the top level project directory (helloworld)

usePlugin('scala')
usePlugin('war')
usePlugin('jetty')

targetCompatibility = 1.5
version = 1

dependencies {
    addMavenRepo()
    addMavenStyleRepo('scala-releases', 'http://scala-tools.org/repo-releases/')

    scalaTools 'org.scala-lang:scala-compiler:2.7.3', 'org.scala-lang:scala-library:2.7.3'
    compile 'org.scala-lang:scala-library:2.7.3', 'net.liftweb:lift-webkit:1.0', 'net.liftweb:lift-util:1.0'
    testCompile 'junit:junit:4.4', 'org.scala-lang:scala-compiler:2.7.3', 'org.mortbay.jetty:jetty:6.1.6'
    testCompile 'org.mortbay.jetty:jetty-util:6.1.6'
    providedCompile 'javax.servlet:servlet-api:2.5'
}

Provided you have gradle in your path, you can run this using

$ gradle jettyRun

This will run jetty until Ctrl-C is pressed and reload the webapp if any changes are detected. The libs task will generate the file build/helloworld-1.war which we will use to deploy to the servers.

While the original pom.xml contains a few more tasks (such as running the YUI Javascript compressor), note that pom.xml is 152 lines  and build.gradle is 17 lines!

Advertisements

2 responses to this post.

  1. Posted by txpete on January 26, 2010 at 00:09

    updates to the build.gradle file to work with gradle .08
    usePlugin(‘scala’)
    usePlugin(‘war’)
    usePlugin(‘jetty’)
    targetCompatibility = 1.5
    version = 1

    repositories {
    mavenRepo urls: “file://” + System.getProperty(‘user.home’) + “/.m2/repository/”
    mavenCentral()
    }

    dependencies {
    // addMavenRepo()
    // addMavenStyleRepo(‘scala-releases’, ‘http://scala-tools.org/repo-releases/’)
    scalaTools ‘org.scala-lang:scala-compiler:2.7.3’, ‘org.scala-lang:scala-library:2.7.3’
    compile ‘org.scala-lang:scala-library:2.7.3’, ‘net.liftweb:lift-webkit:1.0’, ‘net.liftweb:lift-util:1.0’
    testCompile ‘junit:junit:4.4’, ‘org.scala-lang:scala-compiler:2.7.3’, ‘org.mortbay.jetty:jetty:6.1.6’
    testCompile ‘org.mortbay.jetty:jetty-util:6.1.6’
    providedCompile ‘javax.servlet:servlet-api:2.5’
    }

    Reply

    • Posted by Jeppe on January 26, 2010 at 09:21

      Thanks, I’ve been planning for an update of this series since a lot have happened to Gradle, Chef etc. But as always, time is a scarce ressource 🙂

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: