Blog

Powerful Groovy

25 May, 2008
Xebia Background Header Wave

For my current assignment I need to write a script that basically does the following: open war file, download and add files from internet, remove files, change xml and property files, re-package war file.
In pure Java, this would be quite some work to implement. Of course there are several libraries available that will make unzipping, downloading etc a bit easier. But still it would be too much effort for such trivial tasks.
Since it is in fact a script I want to create, why not use a scripting language like Groovy. After two days of coding I must say am very happy with the progress I made given the fact that it is actually my first real Groovy programming experience.
Here are some experiences and code I created so far:

IDE Support
I (used) to work with Eclipse, but the Groovy support for Eclipse is still in progress which was noticeable when using the Groovy Eclipse plugin. It was not really usable in my experience. Since I was already fed up with Eclipse this was actually the final push I needed to switch to IntellJ.
Coding
Now let’s start coding and see how you can implement zipping in Groovy. Groovy already added a lot of convenience methods to the default JDK classes. But wouldn’t it be great if there was also something like an extractTo(destination) method on ZipFile, and a method zip(destination) on File available in Java? Well with Groovy you can quite easily add it yourself using the metaClass and make it available through out your code.
Here is how I added zipping:

class Bootstrapper {
    void boot() {
        File.metaClass.zip = { String destination ->
            def result = new ZipOutputStream(new FileOutputStream(destination))
            result.withStream {zipOutStream->
                delegate.eachFileRecurse { f ->
                    if(!f.isDirectory()) {
                        zipOutStream.putNextEntry(new ZipEntry(f.getPath()))
                        new FileInputStream(f).withStream { inStream ->
                            def buffer = new byte[1024]
                            def count
                            while((count = inStream.read(buffer, 0, 1024)) != -1) {
                                zipOutStream.write(buffer)
                            }
                        }
                        zipOutStream.closeEntry()
                    }
                }
            }
        }
    }
}

What I really really like is the closures for working with streams… No more try-catch-finally-try-finally blocks for closing streams! This is something I really miss in Java.
To zip up a directory you can now just say:

new File("/home/lars/").zip("/tmp/home.zip");

Since I have several methods I added to the JDK classes I created a Bootstrapper class I load on startup of my main Groovy script. This way I have a good oversight on what methods I added myself.
Testing
Another cool thing in Groovy is the build-in JUnit support. You can create unit tests by extending GroovyTestCase and if that is not enough Groovy test cases are runnable out of the box so you can just run a test class using groovy com/xebia/ZipTest.groovy
Conclusion
After just two days of Groovy I started to really like it. One of the nice aspects is that if you don’t know how to do it in Groovy, just use Java and find a more groovy solution later on.
Another thing I noticed is that the lines of code you produce with Groovy is considerably less than the lines of code it would be using Java. Not the mention the fact that I actually included 0 dependencies for my Groovy code. How many would that have been for Java?
And on top of the Groovy icecream the Groovy metaClass gives you a very powerful tool to create more intuitive Java.
I am definitely going to use more Groovy in my future projects.
Lars
PS. All of the functionality I needed for this script are also already offered by Groovy’s build-in AntBuilder.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts