Groovy has access to all java classes, in fact Groovy classes ARE Java classes and can be run by the JVM directly. If you are working on a Java project, using Groovy as a simple scripting language to interact with your java code is a no-brainer.
To make things even better, nearly any Java class can be renamed to .groovy and compiled and run and will work exactly as it did, groovy is close to being a super-set of Java, this is a stated goal of groovy.
Groovy has a REPL. groovysh
comes with Groovy and can be used to quickly instantiate and test a Java class if your classpath is set up correctly. For instance if your classpath
pointed to your eclipse "classes/bin" directory, then you could save your file in eclipse, jump to groovysh
and instantiate the class to test it.
The reasons to use Groovy to do this instead of just Java are:
The classloader is GREAT at picking up new classes as they are compiled. You don't generally need to exit/re-start groovysh
as you develop.
The syntax is TERSE. This isn't great for maintainable code, but for scripts and tests it can cut your code significantly. One of the big things it does is eliminate checked exceptions (or, more accurately, turn all checked exceptions into unchecked exceptions). This turns code like this (Print hello after one second):
class JavaClass {
public static void main(String[] args) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
// You shouldn't leave an empty catch block, but who cares if this was interrupted???
}
System.out.println("Hello!");
}
}
into Groovy's:
Thread.sleep(1000)
print "Hello!"
Groovy also has very tight initialization syntax. This allows you to specify data just as you like it without thinking about it:
In Java to initialize a map you should probably do something like this:
String[] init = { "1:Bill", "2:Doug", "3:Bev" };
// Note the rest of this can be put in a function and reused or maybe found in a library, but I always seem to have to write this function!
Map m = new HashMap<Integer, String>();
for(String pair : int) {
String[] split = pair.split(":");
m.put(new Integer(split[0]), split[1])
}
This isn't bad, but it's something else to maintain. In groovy you would just use:
Map map = { 1 : "Bill", 2 : "Doug", 3 : "Bev" }
And you are done. List syntax is just as easy.
The other really big advantage is groovy's closure syntax. It's amazingly terse and fun, somewhat more difficult to maintain, but for scripts that's not a priority. As an example, here is some groovy code to find all .txt
files that contain the word Hello
in the current directory:
println new File('.').files.findAll{ it.name.endsWith('.txt') && it.text.contains('Hello') }.collect{ it.name }
This example uses a few "Groovy" tricks:
.files
refers to the getFiles()
method - groovy can switch between getter/setter and property syntax at will
it.
refers to the current element of an iteration. { it }
is a shortcut for { it -> it }
, e.g. :
[1, 2, 3].collect{ it ^ 2 } == [1, 4, 9]
it.text
(where it
is a file) uses a method groovy adds to File
to retrieve the entire text of the file. This is amazingly helpful in scripts.