Gr8 Gr8Conf.US Was Gr8

This week I attended Gr8Conf US in Minneapolis. I did a Groovy workshop for Java developers, gave my Making Java Groovy talk, gave a talk on Grails testing, and even managed to throw in an Advanced Groovy Tips and Tricks talk at the last minute when Guillaume Laforge was unable to travel.

(Guillaume said he burned his hand rather badly while cooking. I prefer to believe that he was defending a bunch* of children from a horde of vicious biker ninjas (or possibly Scala developers) intent on world domination. That fits my mental image of him much better. He may look like Clark Kent, but when attacked by a horde of vicious biker ninjas (or possibly Scala developers) he transforms into — well, you know. Seriously, Guillaume, get well soon. You were missed.)

*What is the collective noun for children, anyway? Bunch? Herd? I like “mess”, as in “a mess of children.” Seems appropriate somehow.

This was the third Gr8Conf I’ve attended, and the quality has improved each year. Shaun Jurgemeyer did a great job of organizing, both in the quality and quantity of talks. One thing that was different this year was the Target Hackathon, which was held Sunday evening after the workshops and involved building an application using the Target API. I had what I thought was a good idea, but simply ran out of time, so I’ll save it for next year.

Later I saw pictures of the venue where the Hackathon was held, complete with ping-pong table and outdoor chess set. Like a typical developer, I had my head buried in my laptop the whole time and missed all that. I did manage to sit next to the eventual winner, Todd Miller, who turned out to be a seriously cool guy.

I don’t want to go through the talks I attended one by one, but I do have a few observations:

  • After sitting through Cedric Champeau’s workshop on AST transformations, I have to say I still find them confusing, but at least now my confusion has boundaries. I expect I’ll need to sit down and really dig into the associated chapter in Groovy in Action to understand them.
  • Several talks brought up the new capabilities planned for Grails 2.3, especially involving RESTful web services. I’m looking forward to them, too. What I didn’t expect was the backlash against HATEOAS (Hypermedia As The Engine Of Application State). On the NFJS tour I guess I’ve been hanging out with too many RESTafarians* lately. Peter Ledbrook told me that even David Heinemeier Hansson doesn’t see the benefit of hypermedia, though he’s hardly shy about speaking his mind or going against the popular wisdom. I spent months getting hypermedia to work for my REST chapter in Making Java Groovy**. I still think that was a good investment in time and effort, especially since there are very few good hypermedia examples out there, but maybe I shouldn’t worry so much about the fact that the word “hypermedia” doesn’t even appear in the JAX-RS 2.0 specification.
  • I had no idea how much the tooling in the JavaScript space has evolved. I’d never heard of Grunt, or Bower, or Yeoman, or any of the other tools that come from the nodejs ecosystem. I did hear one good quote, though I can’t remember who said it (probably Zan Thrash but I’m not sure), saying these tools “bring all the joys of downloading the internet to the JavaScript space.” I suppose it seems odd spending so much time on JavaScript at a Groovy conference, but that’s the web world we now live in.
  • I wish I could have seen Luke Daley’s Ratpack presentation, especially after he helped me get the build running at UberConf. Dan Woods managed to implement FOAAS on Ratpack (check it out, but it’s arguably NSFW). At the speaker dinner (thanks, Shaun!), Luke claimed that this was only the second Ratpack app in production, with the first being the Ratpack web site itself. ­čÖé
  • I also wish I could have attended Marco Vermeulen’s talk on GVM. I use GVM all the time and recommend it everywhere, especially if you ever have to change Groovy or Grails versions easily. I finally got to meet Marco, and it turned out he even likes my book***. He’s yet another great guy in the Groovy community. Honestly, the extraordinary friendliness and humility of the developers in the Groovy ecosystem is one of its best features.

*Yah mon, dey be callin’ demselves RESTafarians, which shows much more of a sense of humor than I originally thought they had.

**Are you impressed I made it this far before mentioning my book, Making Java Groovy? I know I am. I just uploaded the revised preface and appendices after the tech review, so everything is still on schedule for an early September release.

***Yeah, that’s probably a humblebrag. Let me turn it into a real brag. At both Gr8Conf and UberConf I had several people tell me how much they liked the book, which feels especially weird (oops, there’s the definitive humblebrag keyword again) because it’s not quite in production yet. Still, that was great to hear.

I feel obligated to do something technical in my blog posts, so let me mention a technique I use a lot and can implement with a tiny bit of metaprogramming. Whenever I need to access a RESTful web service that requires a set of parameters on a query string, I assemble them from a Groovy map.

For example, The web site has a service that generates truly randome numbers “via atmospheric noise,” as they say on the site. To generate a set of random integers base URL is ‘’ and you add a series of parameters to specify what you want. In their main example, they ask for 10 numbers between 1 and 6, in 10 columns, base 10, in plain format using a new generator.

Here’s a quick Groovy script to call it:

String base = ''
def qs = 
    [num:10, min:1, max:6, col:10, base:10, format:'plain', rnd:'new']
        .collect{ k,v -> "$k=$v" }.join('&')
def nums = "$base$qs".toURL().text.split()

I put all the query parameters in a map, then use the collect method to produce a list of “key=value” pairs based on the map entries, and join them using an ampersand. Then I use the toURL method from the String class in the Groovy JDK to turn the address into an instance of, and the text property of the URL class to invoke the getText method. The result is something like:

[4, 1, 4, 6, 3, 3, 1, 4, 3, 3]

I’ve been writing code like that for years, but some time ago the brilliant Paul King told me I could simplify it. It turns out that the toString method in Map.Entry returns “key=value”, so I can write instead:

[num:10, min:1, max:6, col:10, base:10, format:'plain', rnd:'new']
        .collect{ it }.join('&')

He’s right, of course. I still use the more verbose version in presentations to Groovy newcomers, because it’s a bit clearer, but I normally use the simpler one in my own work.

It occurs to me that I can use Groovy metaprogramming to simplify this even further, if I plan to use that construct a lot. Here I add a toQS method to the Map interface.

Map.metaClass.toQS = { -> delegate.collect { it }.join('&') }

def qs = 
    [num:10, min:1, max:6, col:10, base:10, format:'plain', rnd:'new'].toQS()
assert qs == 'num=10&min=1&max=6&col=10&base=10&format=plain&rnd=new'

I get the metaclass from the java.util.Map class* and add a toQS method by assigning it to a closure. Since my method doesn’t take any arguments, I used a zero-argument closure. The delegate property inside the closure refers to the map the closure was invoked on, and the rest is as before.

*Yes, I know java.util.Map is an interface, but it appears as a class in the Groovy JDK.

The final version of the demo script is therefore:

Map.metaClass.toQS = { -> delegate.collect { it }.join('&') }

String base = ''
def qs = 
    [num:10, min:1, max:6, col:10, base:10, format:'plain', rnd:'new'].toQS()
println "$base$qs".toURL().text.split()

There you have it. Now that I think about it, I should probably fork the Groovy project and submit a pull request for it. I’ll probably have to talk to Paul or Guillaume about that.

One last thing: what kind of motorcycle would vicious biker ninjas drive? Harley’s would be way too loud. I presume it would be one of those cool machines like in Tron, all in black.

%d bloggers like this: