Wired For Code

Groovy, Grails and Griffon on Linux.

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.

Continuous Delivery With Grails on CloudBees

For some time I’ve strived at taking the next step after Continuous Integration in my projects: Continuous Delivery. This implies not only automated testing, but also automated deployment. I’ve succeeded in achieving this on bare-metal servers for some time now, but struggled to get this working with Grails in the cloud. The good news is that this is finally possible now!

I recently discovered CloudBees, a Platform as a Service (PaaS) solution for Java applications. What sets them apart from their competition is that they aren’t merely offering a cloud hosting solution, but a hosted CI environment too (read hosted Jenkins!). This is all achieved by leveraging off the stable infrastructure offered by Amazon EC2.

So with a hosted CI server in the cloud, a deployment destination and a Grails runtime available to us, we (almost) have all the components necessary to do end-to-end automated releases. One final puzzle-piece was missing: the CloudBees SDK required to perform deployment from within our Grails project on the Jenkins server. After trying out several things, I opted for writing a Grails Plugin that encapsulates the SDK.

The CloudBees Grails plugin can be installed into any typical Grails project, and adds numerous command scripts for interaction with CloudBees through the SDK. It is possible to deploy, delete, stop, start, restart, list and get app info. You can even tail log files! It is also possible to create, read, update and delete new databases (MySQL databases hosted on Amazon RDS) using the plugin.

Commands

Here is a list of all the available commands that the plugin provides:

bees-app-checksums
bees-app-delete
bees-app-deploy
bees-app-info
bees-app-list
bees-app-restart
bees-app-start
bees-app-stop
bees-app-tail
bees-test-app  
bees-db-create 
bees-db-drop 
bees-db-info 
bees-db-list

Without further ado, let’s jump into using the plugin. We’ll use a small example application which you can pull down from GitHub. We will install the plugin, run some commands on the cloud, and finally set up a Jenkins build that runs tests and deploys the app.

This article assumes that you have an existing CloudBees account and the latest Grails installed on your machine. Also, ensure that your have your CloudBees API key and secret handy.

Getting the Application

The application that we will be using is one that was used to demonstrate Named Queries with Projections in Grails from an earlier post found here. Fork the code found here on GitHub.

Next pull down the source as follows:

$ git clone git@github.com:githubusername/battle-star-galactica.git

replacing githubusername with your own.

Install and Configure the Plugin

Next, step into the project folder, install and configure the plugin:

$ cd battle-star-galactica
$ grails install-plugin cloud-bees

Ensure that your have a .grails folder in your home folder and then create a settings.groovy file in this folder. Now fire up your editor of choice (I’ll be using vim) and edit this file:

$ vi ~/.grails/settings.groovy

Add the following few lines, replacing the key and secret with your own:

cloudbees.account='CLOUD_BEES_ACCOUNT'
cloudbees.api.key='CLOUD_BEES_API_KEY'
cloudbees.api.secret='CLOUD_BEES_API_SECRET'

Add the same config to the BuildConfig.groovy to be used later from within the Jenkins job:

$ vi grails-app/conf/BuildConfig.groovy

Run Some Commands

Let’s test our app, then deploy it straight to the cloud.

$ grails clean
$ grails bees-test-app
$ grails prod war
$ grails bees-app-deploy

Give the command some time to complete and start up the application, then navigate to the url that is dumped to the console. Remember, give it some time to deploy!

My account name is hashcode, so in my case it was: http://bsg.hashcode.cloudbees.net

Next, let’s start configuring the CI environment…

Setting up Jenkins

I won’t go into the detail of how Jenkins works, or even how to configure it in fine detail. Instead I’ll show only the bits that matter.

Firstly we need to install the Grails plugin for Jenkins. After logging into CloudBees, click on the ‘>>Take me to Jenkins’ button. Click: Manage Jenkins > Manage Plugins. Under the Available tab, select the Grails Plugin and hit the Install button at the bottom of the page. Once installed, you will need to restart the Jenkins instance.

Next, we go to New Job and create a ‘free-style software project’ with the name of your choosing. In the following screen, we get to set up all the specifics of our new Job. Enter all your SCM details, triggers and anything else that you would normally configure for a new Job.

The bit that we’re interested in is the Build Section. Here is what mine looks like:

Update (20/05/11)

From version 0.1.1 of the plugin, a new script has been added. The bees-test- app script should be used in the place of test-app. It cloaks the test- app script but overrides the system property grails.env to be test. This script works like you would expect the standard test-app script to work.

The interesting bit in the screen-grab is the Targets field. It has a list of targets that need to be executed, of which the last is the most interesting. This calls on the bees-app-deploy script in the cloud-bees Grails plugin to deploy the war file to RUN@cloud.

$ bees-app-deploy bsg 0.1.${env['BUILD_NUMBER']}

This will deploy target/battle-star-galactica-0.1.war to hashcode/bsg, with a version number of 0.1.x.

This follows the same format as we used earlier, although you should remember to enclose the entire command in quotes in order to tell Jenkins that this is a single command. Also noteworthy is the build number that we insert. This will substitute everything between ${} with the current dynamic build number. You can use any of the implicit environment variables that Jenkins provides in the this way.

One final caveat to look out for is the Properties field. Providing the grails.env=DEV will result in ALL THE TARGETS running in the DEV environment. This will include the test-app target, which is not ideal. I’ll be looking at a solution for this soon and will update this post with news. I will possibly look into getting the Jenkins Grails plugin patched to ignore environment on the test-app target, or else writing a Grails plugin that will cloak test-app.

Continuous Delivery

After all is configured, you should be able to push changes to your SCM (provided that you have set your job up to poll your repository), and see the Jenkins build coming to life. Once all the appropriate targets have been invoked, the war file will be deployed to RUN@cloud. It’s handy to watch your Console Output while you’re testing this, since it also provides you with the URL that your application will be deployed to. As before, once deployed, the application needs to be given some time to deploy.

Getting Continuous Deployment working takes some effort to get right. Some tweaking might be necessary to get the process streamlined. Despite this initial investment in time, it results in a process that will save you many hours in the future. You will never need to run another deploy script or scp another WAR to your server environment. Simply push your changes to Git and watch it deployed in the cloud within minutes!

Named Queries With Projections in Grails

I recently faced some challenges while trying to traverse a data model in a Grails application. Thanks to Grails, as well as the friendly community surrounding it, I managed to solve these complex problems with ease.

Because the things I discovered aren’t documented very clearly, I decided to post them here to help others cross the hurdles that I faced.

Let’s begin by looking at the problem that I was trying to solve, as well as a small model to help describe this:

I was watching the first series of Battlestar Galactica (I know I know, I’m WAY behind!). During the second episode the fleet runs into a water shortage and they resort to seeking for water on nearby planets. Imagine if they had Grails! They would be able to write a named query, and locate a moon or planet with water in no time!

The problem I was facing involved a series of cascading one-to-many relationships. I was trying to get hold of the highest order entity by providing lowest order criteria. If they were in a universe containing many Galaxies, that in turn had many Suns, each Sun having many Planets, and each Planet having multiple Moons, we have the perfect model for our example. In other words, looking for Galaxies that have Suns, that have Planets with water, or else have Planets with Moons that have water.

Fortunately for us, the Hibernate Named Queries make this a lot easier. With GORM cloaking Hibernate, it becomes a doddle (if you know how to do it that is!). We will use Hibernate projections within criteria to achieve our goal.

Forgive the contrived nature of these examples, but their primary purpose is to describe the technique of traversing these cascading relationships.

Projection by Property with Aliases

The first example is for the Fleet Commander to locate all the Planet names of Planets that have water. This is to be ordered by Galaxy, Sun and Planet names.

The Named Query that we will use will live in the Galaxy class and will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Galaxy {
    ...
    static namedQueries = {
        findAllByWaterbaringPlanetNames(){
            createAlias 'suns', 's'
            createAlias 's.planets', 'p'

            projections {
                property 'name', 'galaxy'
                property 's.name', 'sun'
                property 'p.name', 'planet'
            }

            eq 'p.water', true

            order 'galaxy'
            order 'sun'
            order 'planet'
        }
    }
    ...
}

Let’s break this down, and examine what each part is doing:

Firstly we need to define aliases for each one-to-many relationship. Every step we take deeper into our model requires an alias building on top of the previous one. So, defining ‘suns’ as ‘s’, we build our subsequent ‘p’ alias of planets on top of ‘s’ by creatAlias 's.planets', 'p'

Next we define our projections. Something to keep in mind is that when we switch to projections, the results are no longer POJOs. These fellers spit out a List of CSVs. In this case, the results will simply be properties of the collections contained in each entity.

After this I define my criterion. In our example, we are looking for planets that have water. Thus we examine the boolean water flag on the Planet entitiy.

In the last step, we introduce ordering clauses. We order first by Galaxy, then Sun and finally Planet.

A typical Spock Specification for testing this query will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    def "find all galaxies that have waterbaring planets descending"() {
        when:
        def results = Galaxy.findAllByWaterbaringPlanetNames().list()

        then:
        results[i][0] == name
        results[i][1] == sun
        results[i][2] == planet
      
        where:
        i    |        name  |      sun  |        planet
        0    |  'galaxy 1'  | 'sun 1 2' | 'planet 1 2 1'
        1    |  'galaxy 1'  | 'sun 1 2' | 'planet 1 2 2'
        2    |  'galaxy 2'  | 'sun 2 3' | 'planet 2 3 1'
    }

If you want to learn more about Spock, check it out here.

Projections by Grouped Property and Count

Now we move onto the more usefull application of the Projection, where we group by certain properties and count by what is represented in the grouping. Let’s try getting a count of all the waterbaring moons in a galaxy, ordered by count descending. (Contrived, remember!)

Our named query would look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Galaxy {
    ...
    static namedQueries = {
        findAllByWaterbaringMoonCountDescending(){
            createAlias 'suns', 's'
            createAlias 's.planets', 'p'
            createAlias 'p.moons', 'm'

            projections {
                groupProperty 'name'
                countDistinct 'm.id', 'moons'
            }

            eq 'm.water', true
            order 'moons', 'desc'
        }
    }

    ...
}

Once again, we begin by setting up our aliases. Next we introduce our projections, grouping by Galaxy name, counting the amount of distinct moon instances. We then define our criterion, checking if the boolean water field on Moon is true. Lastly, we order by moon count descending.

Now we know which Galaxies Commander Adama needs to target to find the most water!

Spock Spec follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
    def "find all galaxies that have waterbaring moons descending"() {
        when:
        def results = Galaxy.findAllByWaterbaringMoonCountDescending().list()
      
        then:
        results[i][0] == name
        results[i][1] == waterMoons

        where:
        i    |        name  | waterMoons
        0    |  'galaxy 1'  |          2
        1    |  'galaxy 3'  |          1
    }

Well, that’s all for now. Please feel free to clone the source of this example app from GitHub. The best way to master this is to play around with some examples. Also, please feel free to drop me a comment or ask me any questions below.

Enjoy messing around with named queries in Grails. I’m off to watch some more BSG episodes! So say we all! Cheers, Marco.

How to Use Nero AAC Codec With Grip CD Ripper

For quite some time I had been in search of a codec that would work well for my mobile devices. At home, I tend to use FLAC when streaming to my Logitech Squeezebox devices, but when I’m commuting, I listen to music on my phone.

As we all know, space always seems to be an issue on mobile devices. Especially true if you have a sizeable music collection! As a result, I began searching for codecs that provided the highest quality audio, with the smallest disc footprint. I finally settled upon 2 alternatives: Musepack and AAC.

Of the two, Musepack seems to be the highest quality, yet sadly is not widely adopted and supported. AAC on the other hand seems to have taken off well, and is supported on most mobile devices including those fruit flavoured ones!

After looking at codecs that worked on Linux, the choice was narrowed down to 2 contenders: faac (lousy quality and outdated), and Nero AAC (great quality, free, yet not open source). I ended up opting for the latter, being highly rated in shootouts on audio forums. Nero AAC always seem to come in at the top of the list along with the QuickTime codecs from Apple. What further swayed me was the native Linux tools.

So here is a quick howto on getting it working from within the Grip CD Ripper:

Install the Binaries

Start off by fetching the latest archive containing the binaries from the Nero website. Agree to their terms, provide an email address and download. Next, unzip the archive and move the binaries to a bin folder in your path. Also give them executable rights:

$ mkdir /tmp/nero
$ cd /tmp/nero
$ unzip /path/to/downloaded/NeroAACCodec-1.5.1.zip
$ sudo cp /tmp/nero/linux/neroAac* /usr/local/bin
$ sudo chmod +x /usr/local/bin/neroAac*

Create a wrapper script for the binaries

Use your favourite editor to create a wrapper script to invoke the binaries from within your CD ripper software. Type gedit /tmp/nero/neroaac and paste the following into the file:

1
2
3
#!/bin/bash
neroAacEnc -q $1 -if "$2" -of "$3"
neroAacTag "$3" -meta:title="$4" -meta:artist="$5" -meta:comment="Encoded with Nero AAC" -meta:track="$6" -meta:album="$7" -meta:year="$8"

After saving, move this into your path:

sudo mv /tmp/nero/neroaac /usr/local/bin/
sudo chmod +x /usr/local/bin/neroaac

Configure Grip

Lastly, we need to configure Grip to use this wrapper script. Here is what my configuration looks like:

Alternatively, you could simple copy the content of this pastebin into your home folder as .grip-other and Grip should pick it up as the ‘other’ Encoder option under Config -> Encode -> Encoder

Hope you get it all working, please drop me a note with any feedback.

Cheers, Marco.

Install Grip CD Ripper on Ubuntu Through PPA

Hi all,

Some time ago I posted an article regarding the old CD Ripper Grip. I managed to resurrect it from the dead on modern Ubuntu Linux distros. The process I described was quit techie, involving compilation from source.

I finally got around to putting up an Ubuntu PPA where you can download and install it with ease. At the moment I only provide version 3.3.1 for Maverick (both 32bit and amd64), but Natty will follow shortly as soon as it’s released. If I receive requests, I will gladly put up versions for older releases of Ubuntu. Just give me a shout.

So let’s get down to business. How do we install it? Simple! Fire up a console and type in the following few commands:

$ sudo add-apt-repository ppa:vermeulen-mp/grip
$ sudo apt-get update
$ sudo apt-get install grip

Enter your password when prompted, and answer yes wherever needed. That’s it! Hope you enjoy this as much as I did putting it out there. Cheers, Marco.

Happy ripping!