by Dierk Koenig, with Andrew Glover, Paul King, Guillaume Laforge, and Jon Skeet

Book excerpt: Your way to Groovy

news
Jan 26, 200718 mins

All the power of the Java platform can be harnessed with Groovy

The Groovy Website gives one of the best definitions of Groovy: “Groovy is an agile dynamic language for the Java Platform with many features that are inspired by languages like Python, Ruby and Smalltalk, making them available to Java developers using a Java-like syntax.”

Groovy is often referred to as a scripting language—and it works very well for scripting. It’s a mistake to label Groovy purely in those terms, though. It can be precompiled into Java bytecode, be integrated into Java applications, power Web applications, add an extra degree of control within build files, and be the basis of whole applications on its own—Groovy is too flexible to be pigeon-holed.

What we can say about Groovy is that it is closely tied to the Java platform. This is true in terms of both implementation (many parts of Groovy are written in Java, with the rest being written in Groovy itself) and interaction. When you program in Groovy, in many ways, you’re writing a special kind of Java. All the power of the Java platform—including the massive set of available libraries—is there to be harnessed.

Does this make Groovy just a layer of syntactic sugar? Not at all. Although everything you do in Groovy could be done in Java, it would be madness to write the Java code required to work Groovy’s magic. Groovy performs a lot of work behind the scenes to achieve its agility and dynamic nature. As you read this book, try to think every so often about what would be required to mimic the effects of Groovy using Java. Many of the Groovy features that seem extraordinary at first—encapsulating logic in objects in a natural way, building hierarchies with barely any code other than what is absolutely required to compute the data, expressing database queries in the normal application language before they are translated into SQL, manipulating the runtime behavior of individual objects after they have been created—all of these are tasks that Java cannot perform. You might like to think of Groovy as being a “full color” language compared with the monochrome nature of Java—the miracle being that the color pictures are created out of lots of carefully engineered black and white dots.

Let’s take a closer look at what makes Groovy so appealing, starting with how Groovy and Java work hand-in-hand.

Note: This article is an excerpt from Groovy in Action, by Dierk Koenig, with Andrew Glover, Paul King, Guillaume Laforge, and Jon Skeet (Manning Publications, January 2007; ISBN: 1932394842).

Playing nicely with Java: seamless integration

Being Java friendly means two things: seamless integration with the Java Runtime Environment and having a syntax that is aligned with Java.

Seamless integration

Figure 1 shows the integration aspect of Groovy: It runs inside the Java Virtual Machine and makes use of Java’s libraries (together called the Java Runtime Environment, or JRE). Groovy is only a new way of creating ordinary Java classes—from a runtime perspective, Groovy is Java with an additional jar file as a dependency.

Figure 1. Groovy and Java join together in a tongue-and-groove fashion

Consequently, calling Java from Groovy is a nonissue. When developing in Groovy, you end up doing this all the time without noticing. Every Groovy type is a subtype of java.lang.Object. Every Groovy object is an instance of a type in the normal way. A Groovy date is a java.util.Date, and so on. Integration in the opposite direction is just as easy. Suppose a Groovy class MyGroovyClass is compiled into a *.class file and put on the classpath. You can use this Groovy class from within a Java class by typing: new MyGroovyClass(); // create from Java.

In other words, instantiating a Groovy class is identical to instantiating a Java class. After all, a Groovy class is a Java class. You can then call methods on the instance, pass the reference as an argument to methods, and so forth. The JVM is blissfully unaware that the code was written in Groovy.

Syntax alignment

The second dimension of Groovy’s friendliness is its syntax alignment. Let’s compare the different mechanisms to obtain today’s date in Java, Groovy, and Ruby in order to demonstrate what alignment should mean:

import java.util.*; // Java
Date today = new Date(); // Java

today = new Date() // a Groovy Script

require 'date' # Ruby
today = Date.new # Ruby

The Groovy solution is short, precise, and more compact than normal Java. Groovy does not need to import the java.util package or specify the Date type; moreover, Groovy doesn’t require semicolons when it can understand the code without them. Despite being more compact, Groovy is fully comprehensible to a Java programmer.

The Ruby solution is listed to illustrate what Groovy avoids: a different packaging concept (require), a different comment syntax, and a different object-creation syntax. Although the Ruby way makes sense in itself (and may even be more consistent than Java), it does not align as nicely with the Java syntax and architecture as Groovy does.

Now you have an idea what Java friendliness means in terms of integration and syntax alignment. But how about feature richness?

Power in your code: a feature-rich language

Giving a list of Groovy features is a bit like giving a list of moves a dancer can perform. Although each feature is important in itself, it’s how well they work together that makes Groovy shine. Groovy has three main types of features over and above those of Java: language features, libraries specific to Groovy, and additions to the existing Java standard classes (GDK). Figure 2 shows some of these features and how they fit together. The shaded circles indicate the way that the features use each other. For instance, many of the library features rely heavily on language features. Idiomatic Groovy code rarely uses one feature in isolation—instead, it usually uses several of them together, like notes in a chord.

Figure 2. Many of the additional libraries and JDK enhancements in Groovy build on the new language features. The combination of the three forms a “sweet spot” for clear and powerful code. Click on thumbnail to view full-sized image.

Unfortunately, many of the features can’t be understood in just a few words. Closures, for example, are an invaluable language concept in Groovy, but the word on its own doesn’t tell you anything. We won’t go into all the details now, but here are a few examples to whet your appetite.

Listing a file: closures and I/O additions

Closures are blocks of code that can be treated as first-class objects: passed around as references, stored, executed at arbitrary times, and so on. Java’s anonymous inner classes are often used this way, particularly with adapter classes, but the syntax of inner classes is ugly, and they’re limited in terms of the data they can access and change.

File handling in Groovy is made significantly easier with the addition of various methods to classes in the java.io package. A great example is the File.eachLine method. How often have you needed to read a file, a line at a time, and perform the same action on each line, closing the file at the end? This is such a common task, it shouldn’t be difficult—so in Groovy, it isn’t.

Let’s put the two features together and create a complete program that lists a file with line numbers:

 def number=0
new File ('test.groovy').eachLine { line ->
   number++
   println "$number: $line"
}

The closure in curly braces gets executed for each line, and File‘s new eachLine method makes this happen.

Printing a list: Collection literals and simplified property access

java.util.List and java.util.Map are probably the most widely used interfaces in Java, but there is little language support for them. Groovy adds the ability to declare list and map literals just as easily as you would a string or numeric literal, and it adds many methods to the collection classes.

Similarly, the JavaBean conventions for properties are almost ubiquitous in Java, but the language makes no use of them. Groovy simplifies property access, allowing for far more readable code.

Here’s an example using these two features to print the package for each of a list of classes. Note that the word package needs to be quoted because it’s a keyword, but it can still be used for the property name. Although Java would allow a similar first line to declare an array, we’re using a real list here—elements could be added or removed with no extra work:

 def classes = [String, List, File]
for (clazz in classes)
{
   println clazz.'package'.name
}

In Groovy, you can even avoid such commonplace for loops by applying property access to a list—the result is a list of the properties. Using this feature, an equivalent solution to the previous code is println( [String, List, File].'package'.name ) to produce the output ["java.lang", "java.util", "java.io"]. Pretty cool, eh?

XML handling the Groovy way: GPath with dynamic properties

Whether you’re reading it or writing it, working with XML in Java requires a considerable amount of work. Alternatives to the W3C DOM make life easier, but Java itself doesn’t help you in language terms—it’s unable to adapt to your needs. Groovy allows classes to act as if they have properties at runtime even if the names of those properties aren’t known when the class is compiled. GPath was built on this feature, and it allows seamless XPath-like navigation of XML documents.

Suppose you have a file called customers.xml such as this:

 <?xml version="1.0" ?>
<customers>
   <corporate>
      <customer name="Bill Gates" company="Microsoft" />
      <customer name="Steve Jobs" company="Apple" />
      <customer name="Jonathan Schwartz" company="Sun" />
   </corporate>

   <consumer>
      <customer name="John Doe" />
      <customer name="Jane Doe" />
   </consumer>
</customers>

You can print out all the corporate customers with their names and companies using just the following code. (Generating the file in the first place with Groovy using a Builder would be considerably easier than in Java, too.)

 def customers = new XmlSlurper().parse(new File('customers.xml'))
for (customer in customers.corporate.customer)
{
   println "${customer.@name} works for ${customer.@company}"
}

Even trying to demonstrate just a few features of Groovy, you’ve seen other features in the preceding examples—string interpolation with GString, simpler for loops, optional typing, and optional statement terminators and parentheses, just for starters. The features work so well with each other and become second nature so quickly, you hardly notice you’re using them.

Although being Java friendly and feature-rich are the main driving forces for Groovy, there are more aspects worth considering. So far, we have focused on the hard technical facts about Groovy, but a language needs more than that to be successful. It needs to attract people. In the world of computer languages, building a better mousetrap doesn’t guarantee that the world will beat a path to your door. It has to appeal to both developers and their managers, in different ways.

Community-driven but corporate-backed

For some people, it’s comforting to know that their investment in a language is protected by its adoption as a standard. This is one of the distinctive promises of Groovy. Since the passage of JSR-241, Groovy is the second standard language for the Java platform (the first being the Java language).

The size of the user base is a second criterion. The larger the user base, the greater the chance of obtaining good support and sustainable development. Groovy’s user base is reasonably sized. A good indication is the activity on the mailing lists and the number of related projects.

Attraction is more than strategic considerations, however. Beyond what you can measure is a gut feeling that causes you to enjoy programming or not.

The developers of Groovy are aware of this feeling, and it is carefully considered when deciding upon language features. After all, there is a reason for the name of the language: “A situation or an activity that one enjoys or to which one is especially well suited (found his groove playing bass in a trio). A very pleasurable experience; enjoy oneself (just sitting around, grooving on the music). To be affected with pleasurable excitement. To react or interact harmoniously.” [

Someone recently stated that Groovy was, “Java-stylish with a Ruby-esque feeling.” We cannot think of a better description. Working with Groovy feels like a partnership between you and the language, rather than a battle to express what is clear in your mind in a way the computer can understand.

Of course, while it’s nice to “feel the groove,” you still need to pay your bills. In the next section, we’ll look at some of the practical advantages Groovy will bring to your professional life.

What Groovy can do for you

Depending on your background and experience, you are probably interested in different features of Groovy. It is unlikely that anyone will require every aspect of Groovy in their day-to-day work, just as no one uses the whole of the mammoth framework provided by the Java standard libraries.

This section presents interesting Groovy features and areas of applicability for Java professionals, script programmers, and pragmatic, extreme, and agile programmers. We recognize that developers rarely have just one role within their jobs and may well have to take on each of these identities in turn. However, it is helpful to focus on how Groovy helps in the kinds of situations typically associated with each role.

Groovy for Java professionals

If you consider yourself a Java professional, you probably have years of experience in Java programming. You know all the important parts of the Java Runtime API and most likely the APIs of a lot of additional Java packages.

But—be honest—there are times when you cannot leverage this knowledge, such as when faced with an everyday task like recursively searching through all files below the current directory. If you’re like us, programming such an ad-hoc task in Java is just too much effort.

But as you will learn in this book, with Groovy you can quickly open the console and type: groovy -e "new File('.').eachFileRecurse { println it }" to print all filenames recursively.

Even if Java had an eachFileRecurse method and a matching FileListener interface, you would still need to explicitly create a class, declare a main method, save the code as a file, and compile it, and only then could you run it. For the sake of comparison, let’s see what the Java code would look like, assuming the existence of an appropriate eachFileRecurse method:

 public class ListFiles { // JAVA !!
   public static void main(String[] args) {
      new java.io.File(".").eachFileRecurse(
         new FileListener() {
            public void onFile (File file) {
               System.out.println(file.toString());
            }
         }
      );
   }
}

Notice how the intent of the code (printing each file) is obscured by the scaffolding code Java requires you to write in order to end up with a complete program.

Besides command-line availability and code beauty, Groovy allows you to bring dynamic behavior to Java applications, such as through expressing business rules, allowing smart configurations, or even implementing domain specific languages.

You have the options of using static or dynamic types and working with precompiled code or plain Groovy source code with on-demand compiling. As a developer, you can decide where and when you want to put your solution “in stone” and where it needs to be flexible. With Groovy, you have the choice.

This should give you enough safeguards to feel comfortable incorporating Groovy into your projects so you can benefit from its features.

Groovy for script programmers

As a script programmer, you may have worked in Perl, Ruby, Python, or other dynamic (non-scripting) languages such as Smalltalk, Lisp, or Dylan.

But the Java platform has an undeniable market share, and it’s fairly common that folks like you work with the Java language to make a living. Corporate clients often run a Java standard platform (e.g., Java EE), allowing nothing but Java to be developed and deployed in production. You have no chance of getting your ultraslick scripting solution in there, so you bite the bullet, roll up your sleeves, and dig through endless piles of Java code, thinking all day, “If I only had [your language here], I could replace this whole method with a single line!” We confess to having experienced this kind of frustration.

Groovy can give you relief and bring back the fun of programming by providing advanced language features where you need them: in your daily work. By allowing you to call methods on anything, pass blocks of code around for immediate or later execution, augment existing library code with your own specialized semantics, and use a host of other powerful features, Groovy lets you express yourself clearly and achieve miracles with little code.

Just sneak the groovy-all-*.jar file into your project’s classpath, and you’re there.

Today, software development is seldom a solitary activity, and your teammates (and your boss) need to know what you are doing with Groovy and what Groovy is about.

Groovy for pragmatic programmers, extremos, and agilists

If you fall into this category, you probably already have an overloaded bookshelf, a board full of index cards with tasks, and an automated test suite that threatens to turn red at a moment’s notice. The next iteration release is close, and there is anything but time to think about Groovy. Even uttering the word makes your pair-programming mate start questioning your state of mind.

One thing that we’ve learned about being pragmatic, extreme, or agile is that every now and then you have to step back, relax, and assess whether your tools are still sharp enough to cut smoothly. Despite the ever-pressing project schedules, you need to sharpen the saw regularly. In software terms, that means having the knowledge and resources needed and using the right methodology, tools, technologies, and languages for the task at hand.

Groovy will be an invaluable tool in your box for all automation tasks that you are likely to have in your projects. These range from simple build automation, continuous integration, and reporting, up to automated documentation, shipment, and installation. The Groovy automation support leverages the power of existing solutions such as Ant and Maven, while providing a simple and concise language means to control them. Groovy even helps with testing, both at the unit and functional levels, helping us test-driven folks feel right at home.

Hardly any school of programmers applies as much rigor and pays as much attention as we do when it comes to self-describing, intention-revealing code. We feel an almost physical need to remove duplication while striving for simpler solutions. This is where Groovy can help tremendously.

Before Groovy, I used other scripting languages (preferably Ruby) to sketch some design ideas, do a spike—a programming experiment to assess the feasibility of a task—and run a functional prototype. The downside was that I was never sure if what I was writing would also work in Java. Worse, in the end, I had the work of porting it over or redoing it from scratch. With Groovy, I can do all the exploration work directly on my target platform.

The seamless interplay of Groovy and Java opens two dimensions of optimizing code: using Java for code that needs to be optimized for runtime performance, and using Groovy for code that needs to be optimized for flexibility and readability.

Along with all these tangible benefits, there is value in learning Groovy for its own sake. It will open your mind to new solutions, helping you to perceive new concepts when developing software, whichever language you use.

No matter what kind of programmer you are, we hope you are now eager to get some Groovy code under your fingers.

Dierk Koenig is a senior software developer, mentor and coach. He publishes in leading German magazines on software development and speaks at international conferences. He works at Canoo Engineering AG, Basel, Switzerland, where he is the founding partner and member of the executive board. He joined the Groovy project in 2004 working as a committer ever since.

Andrew Glover is the president of Stelligent Incorporated. He actively blogs about software quality at thediscoblog.com and testearly.com.

Dr Paul King is managing director and principal consultant for ASERT, an Australian company specialising in helping its customers leverage emerging technologies. He has provided technical and strategic consulting to hundreds of organizations throughout the U.S. and Asia Pacific and is an active contributor to many open source projects.

As the official Groovy Project Manager and member of the JSR-241 Expert Group standardizing the Groovy Scripting Language, Guillaume Laforge is a passionate Groovy developer. In his professional career, Guillaume is a software architect and open source consultant, working for OCTO Technology, a company focusing on architecture of software and information systems

Jon Skeet is a software engineer and inveterate technological dabbler who happens to specialise in Java and C# development. A recent convert to Groovy, Jon is fanatical about using smarter ways to write cleaner, more readable code.