The Artima Developer Community
Sponsored Link

Cool Tools and Other Stuff
JavaOne 2005, Day 1: It's a Groovy Day
by Eric Armstrong
June 28, 2005
Groovy is a Java-compatible scripting language that blends features from Ruby, Python, and Smalltalk. If you need robust ANT scripts, super shell scripts, or want to write fast unit tests, you may want to try something Groovy, for a change.


God, I love the JavaOne conference. Running from session to session; sipping information through one fire hose after another; writing my reports in the evenings, in the mornings, and in spare moments during the day--and guzzling caffeine to get it all done. But even more stimulating than the caffeine is the pure intellectual high of discovering new things and finding out how they work. Besides, the walking is good exercise, and pumps my brain full of oxygen. Thank God the convention only lasts 4 days, though. Right now, I'm jazzed. By Friday, I'll be wiped.

As always, I'll be bringing you reports on cool stuff--primarily language features and tools--things you can use to do a better job more quickly and more easily, so you can spend your time doing the things you love most--you know what they are.

First up: An interesting scripting language called "Groovy". There are several Java-compatible scripting languages, of course. But at first glance, this one seems to do a lot of things right--enough to take a closer look, anyway. The 1.0 release is due out in September, so it should be usable in a production setting sometime shortly thereafter. In the meantime, it's recommended for exploration, quick hacks, and anything else that isn't "mission-critical".

A Groovy Introduction

Let's start by motivating the discussion: Why do you care about a new scripting language, no matter how good it is? There are several reasons, according to Rod Cope, of OpenLogic, Inc.:

  1. ANT Scripts. Have you ever needed to write a loop or a conditional test in an ANT script? Darn near impossible, right? Groovy makes it easy to insert code segments into your ANT script. Once there, you can access ANT functions as APIs. For example, you can code ant.jar ... to access the ANT task that generates a jar file.
  2. Unit Tests. Unit tests be good--so anything that lets you generate them rapidly be also good. Built-in classes like GroovyTestCase and GroovyMock make it easy to generate test cases and mock objects (objects that have the same APIs as real objects, but which return constant values, instead of performing real functions. They let you isolate part of your application for testing, so the parts it depends on don't have to be functionally correct, or even operational). Note, though, that unit tests also have to be maintainable. See The Cautionary Tale below.
  3. Shell Scripts. The jury hasn't quite come in yet, but Groovy looks as though it may be a useful replacement for shell scripts . It supports pipes, cat, grep--all the stuff you love in Unix scripts. So the Groovy scripts figure to be (a) powerful, (b) portable, and (c) runnab;e on Windows, which is as script-deprived as you can get. (I've been tempted to switch to Max OS/X just to take advantage of the TCSH shell underneath the GUI. Groovy looks like a better answer)
  4. Generate and process hierarchical data. Like XML and XHTML. Easily.
  5. Replace XSLT for XML transformations. Use Groovy instead, write a syntax-translator so you can edit something readable, or for a fun thesis project, come up with a process to convert an algorithm writtin in Groovy to its XSLT equivalent.
  6. Launch an ActiveX-enabled app--like Word, Excel, Access, or IE. Display the window or keep it hidden. Print a set of files, perform a series of searches, or generate HTML pages in Word. Carry out calculations in Excel. Get data from Access. Automated testing of a web app by launching IE, accessing a servlet, and checking values in the DOM.
  7. Generally make life easier. Because Groovy does, well, pretty groovy things--intelligently.

Groovy classes are binary-compatible with Java, and the syntax is compatible as well, so you pretty much write Java. Semi-colons are optional, though, so it's a good idea to use a programming editor that lets you indent things easily and keeps the indentations regular.

For a comparison to BeanShell, see JavaOne 2005 WrapUp: BeanShell vs. Groovy.

More Groovy Features

You can play with things interactively, which is always fun. Using groovysh (the Groovy shell), you type in some commands and then type go to make them execute. That's pretty cool for "lab exercises", when you're trying to find out what an API really does--for example, does it return null, and empty object, or throw an exception when you pass in a funny parameter? Since the API probably doesn't tell you, you can write a quick little experiment and mark down the results in your "lab notebook".

Where Groovy really shines, though, is its capacity for intelligent code generation. It does a lot of the grunt work for you, which makes it a lot easier to write code. For example, when you add a button to a GUI, you simply specify the code to execute when the button is pressed. There's no need to code listeners or call back methods.

Regular-expression processing is built-in, along with robust string processing and file processing, which makes it pretty convenient for those "quick and dirty" hacks where you're converting files from one form to another.

The language makes it easy to process collections, as well, with a built in method (each) to iterate over them. You code something like cars.each(car), and "car" takes on the value of each item in the list of cars. (Multiple syntax choices are available here. See The Cautionary Tale, below.)

It's also pretty darn easy to generate and parse hierarchical data structures like XML, xHTML, and other formats. The functions are built-in, so it only takes a couple of lines of code to parse an XML data set, for example, or to write out a nested collection in XML form.

For SQL, things are similarly simple. You create a SQL object with one line of code. With another line, you invoke the execute method, passing an SQL query or update. Groovy takes care of the details. It opens the connection, processes the SQL, and closes the connection.

One of Groovy's more unusual features is the ability to add methods to existing classes in a use block. So if you want a String contains() method instead of having to code String.indexOf(...) != 0 you can effectively add that method to the String class, rather than having to write a subclass.

The presentation highlighted a few other features, as well, without going into them in detail:

The Groovy Details

Here, as best I got them down in my notes, are some of the code segments provided in the presentation. The slides won't be online until sometime after the show, so we'll find out how accurate I was then. (In the meantime, I've learned my lesson! I'm taking my digital camera tomorrow, so I can grab pics of the code segments.)

Create a list

    def people = ['Eric', 'Bill', 'Frank']

Creates a list of strings.

Lists can be heterogenous. So ['Eric', 1, 'Frank'] is a perfectly fine list, as far as Groovy is concerned. But there is a reason that generics are so valuable in Java. The ability to make sure that a collection contains a predictable set of homogenous values is highly desirable in production code. On the other hand, with sufficient testing (note the emphasis) the issue does become moot--and Groovy does make testing easy.

Create a map

    def cars = ['Eric':'Mazda', 'Bill':..., ...]

Adding a colon maps the keys to values.

Create a nested map

    def stuff = ['Eric':['car':'Mazda', 'computer':'PC'], ...

Putting one map inside of another makes a hierarchical data structure.

Convert the map to XML

    xml = new groovy.xml.MarkupBuilder()
    doc = {
       for (entry in stuff)
          person(name:entry.key) {
             for (thing in entry.value)
                item(name:thing.key; type=thing.value)

The names of the elements are specified as part of the code. To specify attributes, you use the @ prefix on a name, as in @type. That XML data set the results looks like this:


Parse an XML data set

  xmlData = """
  toys = new groovy.utils.xmlParser().parseText(xml)

The three quotes open and close the XML data string, so there is no need to escape attribute-quotes inside the string.

Execute SQL and read data from a database

  sql = new groovy.sql.Sql(datasource)
  toys = sql.dataset("toys")

Execute a SQL command to update the database and read the contents of the table named "toys" into an internal map.

Write a GUI app

  swing = new groovy.swing.SwingBuilder()
  frame = swing.frame('title':'...', 'size':[400, 600]) {
    menubar {
       menuItem... --specify name and code for
                              the action to perform {in braces}
    panel {
       label...    --specify label name
       button...  --specify button text and action to perform

The Cautionary Tale

So at this point you're thinking, hey, Groovy might be pretty cool. There is one caveat though:

There are several ways to write the same thing.

For example, you can write int a = 1 to define a variable as an integer, or you can write def a = 1 and let the language processor figure it out. The processor is smart enough to figure out a lot of stuff, which is pretty darn convenient, most of the time. But when I hear the words, "there's usually several ways to do things", the hairs on the back of my neck stand up.

For some reason, that kind of flexibility always seems like a good idea to the folks who create scripting languages. It's the Perl syndrome: Never provide one way to do things if you can create three, and make sure that you can use different syntax styles so that, no matter what language people are used to, they'll feel right at home in this new, wonderful environment that will be surely become popular, because everyone can use it, right?

Well, maybe.

The problem with that approach is that while it makes scripts easier to write, it makes them much harder to read. Every program becomes a compilation of the idiosyncracies of the person who wrote it and the idioms they happened to master. And that it makes it much harder for someone else to read, understand, and modify.

Since Groovy is a Java-compatible scripting language, it's too bad it doesn't follow the rule that helped Java take off so rapidly--when you read Java code, you know exactly what it is doing. There is only one to write read it, because there is one only one possible syntax choice--nothing else compiles. So once you learn the basics, you can read any Java code, no matter who wrote it.

In contrast, the pragmas and macros used in other compiled languages and the multiple syntax choices available in scripting languages like Perl tend to produce "write-only" code. When you need to fix it, you may choose to rewrite it, rather than attempting to figure out what it's doing. That's ok when you're hacking in the garage, but it's not a big thrill for a manager or a coder who is working to meet a deadline.

Hopefully, things won't be quite that bad with Groovy--but's a potential pitfall I wish the designers had chosen to avoid.


Talk Back!

Have an opinion? Readers have already posted 14 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Eric Armstrong adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Eric Armstrong has been programming and writing professionally since before there were personal computers. His production experience includes artificial intelligence (AI) programs, system libraries, real-time programs, and business applications in a variety of languages. He works as a writer and software consultant in the San Francisco Bay Area. He wrote The JBuilder2 Bible and authored the Java/XML programming tutorial available at Eric is also involved in efforts to design knowledge-based collaboration systems.

This weblog entry is Copyright © 2005 Eric Armstrong. All rights reserved.

Sponsored Links


Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use