Wired For Code

all things JVM on Unix

The GVM Software Development Kit

It recently became apparent to me that, although GVM has an API, it isn’t really being consumed by any clients other than the default bash clients provided by GVM. After some interesting exchanges with Noam Tenne and Andres Almiray on Twitter, I decided that providing a convenient SDK that wraps the API would be a great way to encourage others to use it. It could potentially also encourage the writing of new clients.

It was such a new GVM client that encouraged the creation of this project. It’s a new Groovy client called SGVM that uses the API in automated environments. It’s a great idea, and will allow easy integration with GVM on your CI environments.

Another client that I have been contemplating is a desktop application using the incredible Griffon framework. Another option would be have IntelliJ IDEA and Eclipse plugins that use the SDK. All of this is possible depending on the future of this exciting new SDK that can be used by anyone in the Java realm!

The initial release is only a starting point. It currently only features a client wrapper for the API. It allows you to create a new instance, then exposes multiple methods for obtaining information from the API. The source code lives on GitHub, and binaries can be found on Bintray.

In order to make this SDK more useful, it would be great to expand the capabilities to interacting with the file system in much the same way as the bash client currently does.

I would like to open this up to the community, and value everyone’s input into what this SDK could potentially become. Please feel free to leave your insights and comments below!

Thanks, Marco.

Deploy to Heroku With Gradle

In a previous post I wrote about deploying Java applications to Heroku. It highlighted the pain experienced in deploying a simple Ratpack application to the Heroku PaaS. We delved into the intricacies of using buildpacks to deploy to Heroku. The good news, this is no longer necessary.

In this post, I will show an easier way of deploying. This method removes the need for explicitly using the Heroku Toolbelt and custom buildpacks. It is also no longer necessary to have Ruby, RVM, or a slew of other Ruby related tech that Java/Groovy devs don’t really need to know about.

All this thanks to the excellent Java API that Heroku have made available for us to use. It is a simple Java library that allows us to interact directly with Heroku. Add to this the ability to work with Git repositories through the JGit library provided by the Eclipse Foundation, and we have all we need to deploy our app from within our project directory. The convenience of it all is wrapped up in a Gradle plugin which handles all this on your behalf.

In fact, all we really need is a JDK on the path, a Gradle installation and a good text editor. Let’s jump right in:

Configuration

For starters, we need to configure our project’s build.gradle file as follows:

buildscript {
    repositories {
        ...
        mavenCentral()
        maven { url 'http://dl.bintray.com/vermeulen-mp/gradle-plugins' }
    }
    dependencies {
        classpath "org.gradle.api.plugins:gradle-heroku:0.9.6"
    }
}


apply plugin: 'heroku'

...

heroku {
    //get this from heroku
    apiKey = 'my-api-key'

    //set this on first run if you don't want a generated name
    //appName = 'some-unique-app-name'

    //set this if you are not happy with the default gradlew buildpack
    //buildpack = 'http://somebuildpack
}

This configures your build to use the heroku plugin. Notice the heroku code block where the plugin configuration lives. The only mandatory field here is the apiKey. This can be retrieved from the Heroku dashboard. The appName is not mandatory on first run, but will need to be configured on subsequent runs. If not present, Heroku will generate an app name on your behalf, and will bind your local git repo to that app instance on Heroku. If you don’t like the generated app names, you can name your application explicitly on first run.

It is also worth mentioning that the apiKey may be extracted to a properties file to address security concerns.

Next, we need to add a Procfile to the root of the project. This tiny file is responsible for bootstrapping the application once it is deployed. The significant line here is the one starting with web:. This will vary depending on what you are attempting to deploy.

Fat Jar apps (Spring Boot and DropWizard)

Create the Procfile in the root folder of the project, adding the following content.

---
default_process_types:
  web: java -jar -Dport=$PORT build/libs/my-springboot-fat.jar

Running this for a Spring Boot or Dropwizard application using a fat jar is sufficient to get you up and running.

Ratpack

Deploying a Ratpack application is almost as simple, but requires a little more tweaking. Firstly, you need to control the root project name that Gradle uses to name it’s startup script. This can be done by adding a settings.gradle file to the root of your project with content like this:

rootProject.name = 'ratpack'

Next, we add our Procfile:

---
default_process_types:
  web: export RATPACK_OPTS="-Dratpack.port=$PORT" && build/install/ratpack/bin/ratpack build/install/ratpack/ratpack.groovy

Buildpacks

If you don’t specify a buildpack in the heroku block of your build.gradle file, the plugin will choose a default buildpack. This buildpack will use the gradle wrapper in your project to prepare your application for deployment. It does the bare minimum, so merely runs the gradlew command within the project directory. This requires that defaultTasks are set within your build file.

Default Tasks

In order for the default buildpack to know what tasks to run, we need to specify the default tasks list in our build.gradle. For instance, to prepare a Ratpack application for deployment you would add the following:

defaultTasks "clean", "build", "installApp"

Adopt a JDK!

The default buildpack even allows you to choose what JDK to use at runtime. Simply drop a system.properties file into the base folder of the project with the following content:

java.runtime.version=1.7

If system.properties is not defined in your project, the buildpack will assume JDK 1.8 on your behalf.

Taking it for a Spin!

So that’s all for configuration, let’s take it out for a drive. Open a terminal and enter the following commands:

1
2
3
4
5
6
7
8
9
10
$ gradle tasks

...
herokuAppCreate - Creates a new application on Heroku.
herokuAppDeploy - Deploy the application to Heroku.
herokuAppDestroy - Destroy the application on Heroku.
herokuAppInfo - Displays comprehensive information about the named application.
herokuAppList - Lists all Apps available for the current user on Heroku.
herokuBuildpack - Downloads and explodes the specified buildpack to this project.
...

Now that we know what we can do, let’s get it deployed. Start by adding the wrapper to git:

1
2
3
$ ./gradlew wrapper
$ git add gradlew gradle
$ git commit -m 'Add wrapper.'

Next create the app on Heroku and deploy:

1
2
$ ./gradlew herokuCreateApp
$ ./gradlew herokuDeployApp

If all is well, you should have a deployed application on heroku!

The source code for both the plugin and the default buildpack can be found on GitHub.

That’s All!

We have seen how easy it has become to deploy applications to Heroku from within a Gradle project. All we need is an api key and some very simple configuration to get our app singing sweetly in the clouds. Deploying to Heroku has never been easier!

GVM on Continuous Integration Environments

I’ve been having conversations with people who want to use GVM on their Continuous Integration build servers. Even though this sounds like a great idea, the GVM client is not very well suited for this purpose. The reason for this is simple: GVM was never designed to be an automation tool, but rather to make developers’ lives easier (read, for humans!).

For some time, I thought about an elegant way to solve this problem for users who specifically want GVM to run in an automated environment. I now think I have a workable solution: As most people know, GVM is not merely a little bash client, but is backed by a REST API to perform it’s work. I set about writing a very light weight bash client, consuming the same API, but specifically designed for the very purpose of automation.

This script can be found in the gvm project under the contrib folder, aptly named download.sh. The script can be copied and used from within your CI environment as follows:

./download.sh <candidate> <version>

This will automatically call through to the gvm API and download the candidate/version into the $HOME/gvm folder. The candidate version archive will be stored in a cache under $HOME/gvm/archives, so will never be downloaded again on future runs. The archive will then be exploded int the gvm folder, leaving you with the following folder structure.

gvm
├── archives
│   └── groovy-2.1.6.zip
└── groovy-2.1.6

You are now free to use this installation of the candidate at will. From your CI build, you can invoke the candidate version by a simple:

. ~/gvm/groovy-2.1.6/bin/groovy

This is only the first iteration of the new client script, so please feel free to comment and leave suggestions. Any feedback is welcome.

Deploying Ratpack Applications on Heroku

Deploying a simple Ratpack application to Heroku is far more complicated than it need be. After much trial and error, I have finally managed to get a working configuration for successful deployment. This post details how to go about the process using manual steps. A subsequent post will cover how to do this using a Gradle plugin to simplify the process.

Artifacts

In order to deploy successfully, certain artifacts need to be present in your project for Heroku to detect your application successfully. These files are rather invasive, so should preferrably not be added to your master branch in version control. Because Heroku uses Git for deployment, I recommend adding them to version control in a new branch as the final step before pushing your application up to Heroku. More of that later…

Firstly, we need a bin folder containing compile and detect scripts.

bin
├── compile
└── detect

The files contain the following:

bin/detect

#!/usr/bin/env bash
# bin/use <build-dir>

if [ -f $1/src/ratpack/ratpack.groovy ]; then
   echo "Ratpack" && exit 0
else
  echo "no" && exit 1
fi

bin/compile

#!/usr/bin/env bash
# bin/compile <build-dir> <cache-dir>

# fail fast
set -e

BIN_DIR=$(cd $(dirname $0); pwd) # absolute path

# parse args
BUILD_DIR=$1
CACHE_DIR=$2

#env variables
JAVA_DIST="openjdk1.7.0_21"
JDK7_URL="https://s3.amazonaws.com/heroku-jdk/${JAVA_DIST}.tar.gz"

#create the cache dir if it doesn't exist
mkdir -p $CACHE_DIR

cd "$BUILD_DIR"

#jdk7
if [ -d .jdk7 ]; then
  echo "-----> .jdk7 folder found, moving along."

else
  echo -n "-----> .jdk7 folder not found! "
  if [[ -d "$CACHE_DIR/.jdk7" ]]; then
    echo -n "Copying jdk from cache to app... "
    cp -r "$CACHE_DIR/.jdk7" "$BUILD_DIR"
    echo "Done!"

  else
    echo -n "-----> Installing ${JAVA_DIST} build (to .jdk7)....."
    mkdir "$BUILD_DIR/.jdk7"
    cd "$BUILD_DIR/.jdk7"
    curl --max-time 180 --location "$JDK7_URL" | tar xz
    cd "$BUILD_DIR"
    echo "Done!"
  fi
fi

cd $BUILD_DIR

export JAVA_HOME="$BUILD_DIR/.jdk7"
export PATH="$JAVA_HOME/bin:$PATH"

echo ""
echo "-----> Building project with Gradle wrapper:"
echo "       ./gradlew clean installApp"
export GRADLE_OPTS="-Dfile.encoding=UTF-8 -server -Xmx512m -XX:+UseCompressedOops"
export GRADLE_USER_HOME="$CACHE_DIR/.gradle"

./gradlew clean installApp

rm -rf "$CACHE_DIR/.jdk7"
cp -r .jdk7 "$CACHE_DIR/.jdk7"

Next, we require a Procfile, living in the root of your Ratpack project.

Procfile

---
addons:
config_vars:
  JAVA_OPTS: -Dfile.encoding=UTF-8 -server -Xmx512m -XX:+UseCompressedOops
default_process_types:
  web: build/install/ratpack/bin/ratpack

The build/install/ratpack/bin/ratpack file, as well as the build/install/ratpack folder appearing in the web process above can be considered as moving targets. This file and folder will be named after the root folder name of your project. It is possible (and necessary) to override this value on deployment to Heroku, since the root project name is derived from a generated hash. In order to fix this, we need to set the root project name to something known (in our case ratpack). This can be configured in the settings file in the root of the project:

settings.gradle

rootProject.name = 'ratpack'

Last but not least, we need to set the RATPACK_OPTS environment variable to the $PORT variable provided to us during the deployment process. This needs to be placed in an obscure script hidden in the bowels of our project under a .profile.d folder.

.profile.d/setenv.sh

#!/bin/bash
echo "Setting environment varialbes..."
export RATPACK_OPTS="-Dratpack.port=$PORT"
export JAVA_HOME="${BUILD_DIR}/.jdk7"

We now have the following new artifacts in our application folder:

├── bin
│   ├── compile
│   └── detect
├── Procfile
├── .profile.d
│   └── setenv.sh
└── settings.gradle

Deployment Process

Next, we need create our new application on Heroku using an inline buildpack. This simple buildpack relays all commands to the artifacts we have created in our project. The command also creates us a Cedar Stack based on Ubuntu 10.04 on Heroku.

heroku apps:create myapplication --buildpack http://github.com/kr/heroku-buildpack-inline.git

Next we switch to our new deploy branch, and commit all these new artifacts here.

git checkout -b deploy
git add bin Procfile settings.gradle .profile.d
git commit -m 'Heroku deployment artifacts.'
git push heroku deploy:master

We should now see our application deploy successfully:

-----> Fetching custom git buildpack... done
-----> Ratpack app detected
-----> .jdk7 folder not found! Copying jdk from cache to app... Done!

-----> Building project with Gradle wrapper:
       ./gradlew clean installApp
<snip/>
-----> Discovering process types
       Procfile declares types -> JAVA_HOME, JAVA_OPTS, web

-----> Compiled slug size: 64.8MB
-----> Launching... done, v38
       http://myapplication.herokuapp.com deployed to Heroku

and we can tail the remote logs to confirm this:

heroku logs --tail --num 100 --app myapplication

In a subsequent post, I will be covering how to perform all of this using an up-and-coming Gradle plugin which is proposed here on GitHub. Source code for all the above can be found here in a GitHub repository.

Groovy enVironment Manager API

Groovy enVironment Manager API

GVM is a tool for managing parallel Versions of multiple Software Development Kits on most Unix based systems. It provides a convenient command line interface for installing, switching, removing and listing Candidates.

It has two main components: the first is a series of bash scripts; the second is a simple lightweight API that the clientside code calls in order to fulfill it’s functions.

Even though the API’s primary purpose has been to serve the clientside bash scripts, it can very easily be utilised by other clients. Examples of this could be an IntelliJ or Eclipse plugin, a rich GUI client (perhaps written in Griffon) or a Windows batch script like Gravy.

To help developers getting started, here follows a list of endpoints, along with request parameters and results:

All Candidates

http://api.gvmtool.net/candidates

Gets all candidates available on GVM.

Result: A comma separated list of candidates of all supported candidates.

gradle, grails, griffon, groovy, vertx

All Candidate Versions

http://api.gvmtool.net/candidates/{candidate}

Example: http://api.gvmtool.net/candidates/gradle

Result: A comma separated list of versions: 0.7, 0.8, 0.9, 0.9.1, 0.9.2, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5

Default Candidate Version

http://api.gvmtool.net/candidates/{candidate}/default

Example: http://api.gvmtool.net/candidates/grails/default

Result: The default version of the candidate: 2.2.1

Candidate Version List

http://api.gvmtool.net/candidates/{candidate}/list

Will render a neat list report of the candidate versions, as well as what is installed and currently active.

Example: http://api.gvmtool.net/candidates/gradle/list?current=1.5&installed=1.3,1.4,1.5

Parameters:

  • current : The current active version.
  • installed : A CSV list of currently installed versions.

Result: A neat list of candidate versions:

============================================================
Available Gradle Versions
============================================================
 > * 1.5
   * 1.4
   * 1.3
     1.2
     1.1
     1.0
     0.9.2
     0.9.1
     0.9
     0.8
     0.7

============================================================
+ - local version
* - installed
> - currently in use
============================================================

Candidate Version Download

http://api.gvmtool.net/candidates/{candidate}/{version}/download

Will redirect to the appropriate candidate version for download.

Example: http://api.gvmtool.net/candidates/groovy/2.1.3/download

Result: The zip archive: groovy-2.1.3.zip

Candidate Version Validation

http://api.gvmtool.net/candidates/{candidate}/{version}/validate

Example: http://api.gvmtool.net/candidates/groovy/2.0.0/validate

Result: The validity of the candidate version combination. valid or invalid

API Version

http://api.gvmtool.net/candidates/api/version

Example: http://api.gvmtool.net/candidates/api/version

Result: The current version deployed. 0.9.6

API Broadcast

http://api.gvmtool.net/api/broadcast

Parameter:

  • version : optional, will return upgrade message if not matching current api version.

Example: http://api.gvmtool.net/api/broadcast/0.9.6

API Alive

http://api.gvmtool.net/api/alive

Result: Checks if the service is running: OK

New Per-Shell Version Feature in GVM 0.9.0

Per-Shell Version

Version 0.9.0 of GVM has been released. This is a major release, although it only contains a single new feature: The Per-Shell Version.

The requirement:

To let each shell run it’s own version of a candidate. In other words, to have one shell open on Grails 2.1.2 and another open on Grails 2.2.0.RC3. Up to now this was not possible. The gvm use command was used to switch a symlink to the current version of choice. This unfortunately meant that switching in one terminal would affect all other terminals too.

The solution:

As from version 0.9.0, we no longer affect all shells by invoking the gvm use command. Instead, we now share the responsibility across two commands: gvm use and gvm default.

The DEFAULT command

We have introduced a brand new command called gvm default. This command is responsible for switching the symlink responsible for choosing the default version when a new shell is opened. You would probably want all new shells to open with the latest version of your installed candidates. For instance, if you want to start every new shell with Gradle 1.3, simply invoke the following command:

gvm default gradle 1.3

It is important to note that this will not switch the current shell to Gradle 1.3. This will default new shells only.

The USE command

The gvm use command is used to perform switching in the current shell. When opening a new shell with the default Gradle set to 1.3, we can easily switch to 1.2 by entering the following command:

gvm use gradle 1.2

This will only affect the current shell.

Big changes

Despite how simple this change may seem, it has brought about huge changes in the way that GVM works. We have converted GVM to be function based, as opposed to command based. This means that performing a selfupdate from a version prior to 0.9.0 up to 0.9.x will require a new shell to be opened. This is done in order to source the new functions that need to be available to the current shell.

Configuration

Don’t like the new changes? You can still tell GVM to behave as it always did by updating the ~/.gvm/etc/config file to contain the following:

isolated_mode=0 

Now GVM will behave as it always did by allowing the gvm use command to switch the default version.

Scenarios

As always, the specification for this new feature is captured in a Cucumber Feature.

Proposal for Convenient Install Tool for Grails, Griffon and Groovy

Some time ago I embarked on providing the Grails, Griffon and Groovy communities with an easy installation method for their development kits on Linux. I went about this by setting up a Personal Package Archive for Ubuntu based Linux distributions. Even though this method has been very successful and been met with much favourable response, I’ve also been thinking about how I could benefit the greater Groovy community (read Mac OSX and Cygwin).

While working with Ruby, I’ve been enjoying the relative(!) ease of use provided by rvm en rbenv. These tools have made working with Ruby much easier, and allow installation and management of multiple versions very easy. On these grounds I started tinkering with a new concept. Wouldn’t it be nice to have an equivalent of rvm for Groovy?

A tool such as this should achieve the following goals:

  • easy of use
  • compliant with any *nix bash shell (Linux, OSX, FreeBSD or Cygwin)
  • written in bash to facilitate easy entry
  • management of Groovy, Grails, Griffon and Gradle candidates
  • allow for installation, listing, switching and deletion of candidates

I would love to hear some feedback from everyone out there. Would people be interested in something like this? Would it be of any use? I’m also interested in hearing what functionality and features people would like to see in such a project.

Please leave some comments/feedback below. I would love to hear what you have to say.

Thanks, Marco.

Release Process for Groovy Ubuntu PPAs

It’s been about a year since I embarked on providing high quality Debian packages of Groovy, Grails and Griffon to the Ubuntu community. The initial learning curve was rather steep, involving a full immersion in the Debian Policy documentation, as well as getting to grips with a myriad of command line tools. Many tools performing similar functions, but each with subtle differences. The method that I finally settled upon is surely not the only way of performing this task, although it produces high quality lintian compliant packages.

This post is my attempt to share what I have learned, and to expose the process that I have set in place. I’m doing this so that others can also get involved, and potentially take over from me one day when I’m through with delivering these packages. Not that I intend to stop delivering these packages any time soon! :–)

Setting up the Environment

Firstly, it is assumed that you will be using a brand new installation of Ubuntu (or Mint) Linux. At the time of writing, 12.04 Precise Pangolin is the flavour of the day and will be used to for the entire setup.

Next, you will need to ensure that you have a GPG key set up in order to sign your packaged artefacts. Because this is outside the scope of this article, you can refer to Ubuntu GNU Privacy Guard Howto for this.

Without any further ado, let’s get right into it and get our environment set up for action. Open a terminal and run the following on the command line:

$ sudo apt-get install build-essential devscripts ubuntu-dev-tools debhelper \
  dh-make diff patch cdbs quilt gnupg fakeroot lintian  pbuilder piuparts

Now that we have all dependencies in place we can proceed by creating a work directory and downloading the latest version of Grails (2.1.0 was the latest at the time of writing).

$ mkdir ~/packages
$ cd packages
$ wget http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.1.0.zip

Unzip the folder and rename it to the format $PACKAGE-$VERSION-$RELEASE. Then we create a tarball out of the archive with the format $PACKAGE-$VERSION_$RELEASE.orig.tar.gz:

$ unzip grails-2.1.0.zip
$ mv grails-2.1.0 grails-2.1.0-1.0
$ tar zcvf grails-2.1.0_1.0.orig.tar.gz grails-2.1.0-1.0

A word about the components of the name here:

  • PACKAGE: grails, groovy or griffon
  • VERSION: 2.1.0 in this case
  • RELEASE: Our package version. This component is a number we use to track the VERSION up to the point when it comes out of RC or beta and into final release. eg. RC1 = 0.1, RC5 = 0.5, GA = 1.0, 2.1.RC4 = 0.4, 2.1.GA = 1.0

We should now have a folder named grails-2.1.0-1.0 and a file named grails-2.1.0_1.0.orig.tar.gz in our work directory. It is crucial to stick to these exact naming conventions.

Now we need to clone the Debian metadata that the packaging tools will use to build our packages from GitHub, placing them inside our exploded zip folder.

$ git clone git@github.com:freshgroovy/grails-ubuntu.git
$ mv grails-ubuntu/debian grails-2.1.0-1.0/

It is noteworthy that GitHub repositories exist for grails-ubuntu, griffon-ubuntu and groovy-ubuntu.

We now have all the files in place, so time to start editing what we have. Step into the grails-2.1.0-1.0 folder. Next we’ll add a few lines of code at the head of the startGrails file (same for startGriffon or startGroovy):

$ cd grails-2.1.0-1.0
$ vi bin/startGrails
1
2
3
4
5
6
7
8
9
10
# Added by groovy-dev for Ubuntu PPA
export GRAILS_HOME="/usr/share/grails/2.1.0"
export JAVA_HOME="$(update-alternatives --query java | grep Value | sed 's_^Value: __g' | sed 's_/jre/bin/java__g')"

##############################################################################
##                                                                          ##
##  Grails JVM Bootstrap for UN*X                                           ##
##                                                                          ##
##############################################################################
...

Next we’ll update all files in the debian folder with appropriate VERSION, RELEASE, PRIORITY and DATE:

1
2
3
4
5
6
7
8
VERSION="2.1.0"
RELEASE="1.0"
PRIORITY="50"
DATE="$(date -R)"
find "debian/" -type f | xargs sed -i "s/VERSION/${VERSION}/g"
find "debian/" -type f | xargs sed -i "s/RELEASE/${RELEASE}/g"
find "debian/" -type f | xargs sed -i "s/PRIORITY/${PRIORITY}/g"
find "debian/" -type f | xargs sed -i "s/DATE/${DATE}/g"

We then rename the install, pre- and post- hooks appropriately:

1
2
3
mv "debian/grails-VERSION.install" "debian/grails-${VERSION}.install"
mv "debian/grails-VERSION.postinst" "debian/grails-${VERSION}.postinst"
mv "debian/grails-VERSION.prerm" "debian/grails-${VERSION}.prerm"

Now that we have performed all edits, it’s time to run the Debian build scripts:

1
dpkg-source --commit

This will generate some patch files under debian/patches for the startGrails file that we edited. Simply save the patch file with a name such as start_grails and exit.

We now build the package:

1
debuild -S -sa

The final step is to run this build in a virtual environment with the pbuilder tool. We will use a handy wrapper for pbuilder that will allow you to run it for multiple distributions of Ubuntu. The wrapper script can be found as part of the ubuntu-dev-tools package:

1
2
3
pbuilder-oneiric create  #only on the first time!
pbuilder-oneiric update
pbuilder-oneiric build "${PACKAGE}-${VERSION}_${RELEASE}-1ubuntu0.dsc"

If all is well, our package is now in the pbuilder folder and we should be able to install it with a simple:

$ sudo dpki -i /path/to/my/deb/grails-2.1.0_1.0-1ubuntu0_all.deb

Congratulations! You’ve built and installed your own Grails package.

The Easier Way

Of course there is an easier way: This entire process can be driven by a script. This script can be found in the ubuntu-release-scripts repository on GitHub and simply needs to be added to your path.

Running without parameters reveals some simple help:

$ groovy2dev

Usage: groovy2dev <zipfile> <package> <version> <release> <priority>

To package the 2.1.0 release of Grails as described earlier, we simply run the following command:

$ groovy2dev /path/to/grails-2.1.0.zip grails 2.1.0 1.0 50

This should run through the entire process described above and result in a grails .deb package in the pbuilder output folder.

One Final Thing

Once packaged, we are ready to release the package into the wild. We do this by issuing one single command on the .changes file that was generated earlier. This can only be done if you have the appropriate authorisation from the groovy-dev group on launchpad.

$ dput ppa:groovy-dev/grails grails-2.1.0_1.0-1ubuntu0_source.changes

Any feedback or questions are welcome so feel free to leave a comment.

Enjoy!

Using a Griffon ComboBox With an EventList

I recently decided to add some new tools to my Groovy toolbox. I decided upon Griffon, a fantastic framework for building rich Swing user interfaces with the same Convention over Configuration paradigm as what Grails offers.

The framework is very is rich in features, but not all of these are documented very readily. I usually need to dig deep into forum archives and obscure articles to find answers to my questions.

When I was confronted with this particular problem using a combobox to trigger an action resulting in another field being updated based on it’s value, I searched long and hard for a solution. When I eventually figured it out I decided to write about it so as to help others who might be looking for a quick answer.

I will present this solution in three simple snippets of code:

The Model

1
2
3
4
5
6
import ca.odell.glazedlists.*  
class MyModel {
   final EventList myList = new BasicEventList()  
   @Bindable String selected  
   //other fields here
}

The View

1
2
3
4
    comboBox(id:'my-combo', model: eventComboBoxModel(source: model.myList),
        actionPerformed: controller.myAction,
        selectedItem: bind(target:model, targetProperty:'selected')
    )

Controller

1
2
3
4
5
6
7
8
class MyController {
   def myAction = {
      //perform some work using model.selected here
   }  
   void mvcGroupInit(Map args) {
      //initialise model.myList
   }
}

We are using the Glazed Lists EventList to back the contents of the ComboBox in our example. This allows us to bind the values contained in the list to our ComboBox. You would need to install the Glazed Lists plugin to get this working: griffon install-plugin glazedlists

On initialisation of our controller, we can add values to this BasicEventList. The interesting part is what happens in our view script:

  • We bind our list to the ComboBox by using the eventComboBoxModel(). This method is provided by the plugin and is now available on our script.
  • We then specify the ComboBox selectedItem attribute to be bound to the selected field in the model. Take not that the selected field is annotated as @Bindable in the model. If a selection is now made on the combo, the value is written to the selected field in the model.
  • Lastly, we assign the actionPerformed to be our controller method. This method will pick up our selected field in the model. Subsequently, it can set another field’s value based on the value of our selected field.

As easy as that! (if you know how, that is)

Git With Meld Diff Viewer on Ubuntu

Using command line Git with standard diff is workable but not very friendly. You might prefer a split-pane diff viewer like that of your favourite IDE. The easiest way to get this working on Debian based Linux distros such as Ubuntu is to use Meld, the open source diff and merge tool.

Begin by installing Meld:

$ sudo apt-get update && sudo apt-get install meld

Once installed, open your favourite text editor and create a file called git- diff.sh, using the following content:

1
2
#!/bin/bash
meld "$2" "$5" > /dev/null 2>&1

Save this to a location such as /usr/local/bin, giving it executable rights:

$ sudo mv git-diff.sh /usr/local/bin/
$ sudo chmod +x /usr/local/bin/git-diff.sh

The final step is to open your $HOME/.gitconfig file and add the following few lines:

1
2
[diff]
        external = /usr/local/bin/git-diff.sh

The next time you type git diff in a Git project with changes, Meld will be launched showing you a split-pane diff viewer. Note that you are required to close the open instance of meld before the next diff viewer is opened.