Groovy Adaptable Packaging Engine (GRAPE)

I think I am falling in love with groovy all over again. GRAPE is a fantastic addition to Groovy 1.6.x. Transitive dependency management is becoming more and more common with the JAR hell that java/groovy application developers face. With the number of libraries growing exponentially and complex interdependence between them - to start a java project with any complexity one has to maintain a huge stash of jars and the overhead required to maintain them is unbelievable. One reason why projects like Grails/App fuse have been successful is that they reduce the ramp up time to develop something interesting. For me a major part of the ramp up time is setting up all the libraries - spring, hibernate, eh-cache (and all the dependent libraries). Open source build tools like IVY and Maven have taken transitive dependency management to the next level and GRAPE builds the capability inside the language itself.

By placing a couple of really simple annotations - one can forget about the dependent jars altogether. The packages will be downloaded automatically and used before executing the script.

So lets say I have a simple script that depends on commons-logging.

I can use it inside my script like this:

import org.apache.commons.logging.*;

@Grab(group = 'commons-logging', module = 'commons-logging', version='1.1.1')
public class GrapeTest {
	static Log logger = LogFactory.getLog(GrapeTest.class);
	public static void main(String[] args) {
		//log
		logger.info("Hello world from Grape!")

	}
}

Here the group is the maven GroupId and the module is the maven ArtifactId. On the command line all I do is groovy <fileName> and the jar download and classpath resolution etc. are handled transparently:

deepti@aanyalaptop /cygdrive/c/Users/deepti/Desktop
$ groovy test.groovy
Dec 16, 2009 12:24:49 AM sun.reflect.NativeMethodAccessorImpl invoke0
INFO: Hello world from Grape!

deepti@aanyalaptop /cygdrive/c/Users/deepti/Desktop
$

If one takes a look the downloded files are present in ~/.groovy/grapes/…

deepti@aanyalaptop /cygdrive/c/Users/deepti
$ find . -name commons*.jar -print
./.groovy/grapes/commons-logging/commons-logging/jars/commons-logging-1.1.1.jar

deepti@aanyalaptop /cygdrive/c/Users/deepti
$

Incredibly simple - what is cool is that the grape handles transitive dependencies transparently - so all the libraries on which commons-logging depends will be downloaded and installed automatically.

So now one can ship a groovy script (piece of code) without any dependencies. Very interesting and very useful.