The groovy Ant Task

<groovy>

Description

Executes a series of Groovy statements. Statements can either be read in from a text file using the src attribute or from between the enclosing Groovy tags.

Required taskdef

Assuming groovy-all-VERSION.jar is in my.classpath you will need to declare this task at some point in the build.xml prior to using this task.

<taskdef name="groovy"
         classname="org.codehaus.groovy.ant.Groovy"
         classpathref="my.classpath"/>

<groovy> attributes

Attribute Description Required
src File containing Groovy statements.
The directory containing the file is added to the classpath
Yes, unless statements enclosed within tags
classpath the classpath to use No
classpathref the classpath to use, given as reference to a PATH defined elsewhere No

Parameters specified as nested elements

<classpath>

Groovy's classpath attribute is a PATH like structure and can also be set via a nested classpath element.

<arg> (since 1.1)

Arguments can be set via one or more nested <arg> elements using the standard Ant command line conventions.

Available bindings

A number of bindings are in scope for use within your Groovy statements.

Name Description
ant an instance of AntBuilder that knows about the current ant project
project the current ant project
properties a Map of ant properties
target the owning target that invoked this groovy script
task the wrapping task, can access anything needed in org.apache.tools.ant.Task
args command line arguments, if any

Examples

Hello world, version 1:

<groovy>
println "Hello World"
</groovy>

Hello world, version 2:

<groovy>
ant.echo "Hello World"
</groovy>

List all xml files in the current directory:

<groovy>
xmlfiles = new File(".").listFiles().findAll{ it =~ "\.xml$" }
xmlfiles.sort().each { println it.toString() }
</groovy>

List all xml files within a jar:

<zipfileset id="found" src="foobar.jar"
            includes="**/*.xml"/>
<groovy>
    project.references.found.each {
        println it.name
    }
</groovy>

To run a script:

<groovy src="/some/directory/some/file.groovy">
  <classpath>
    <pathelement location="/my/groovy/classes/directory"/>
  </classpath>
</groovy>

To find all the 'Builder' classes having an 'org.*' package within a directory of jars:

<property name="local.target" value="C:/Projects/GroovyExamples"/>
<groovy>
import java.util.jar.JarFile
def classes = []
def resourceNamePattern = /org\/.*\/.*Builder.class/
def jarNamePattern = /.*(beta|commons).*jar$/

def libdir = new File("${properties['local.target']}/lib")
libdir.listFiles().grep(~jarNamePattern).each { candidate ->
    new JarFile(candidate).entries().each { entry ->
        if (entry.name ==~ resourceNamePattern) classes += entry.name
    }
}
properties["builder-classes"] = classes.join(' ')
</groovy>
<echo message='${builder-classes}'/>

Which might result in something like:

org/apache/commons/cli/PatternOptionBuilder.class org/apache/commons/cli/OptionBuilder.class org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.class org/custommonkey/xmlunit/HTMLDocumentBuilder.class org/custommonkey/xmlunit/TolerantSaxDocumentBuilder.class

FileScanner version of above (with a slight variation on collecting the names):

<groovy>
import java.util.jar.JarFile
def resourceNamePattern = /org\/.*\/.*Builder.class/
def candidates = ant.fileScanner {
    fileset(dir: '${local.target}/lib') {
        include(name: '*beta*.jar')
        include(name: '*commons*.jar')
    }
}
def classes = candidates.collect {
    new JarFile(it).entries().collect { it.name }.findAll {
        it ==~ resourceNamePattern
    }
}.flatten()
properties["builder-classes"] = classes.join(' ')
</groovy>

Setting arguments

<target name="run">
        <groovy>
            <arg line="1 2 3"/>
            <arg value="4 5"/>
            println args.size()
            println args[2]
            args.each{ ant.echo(message:it) }
        </groovy>
    </target>
Buildfile: GROOVY-2087.xml

run:
   [groovy] 4
   [groovy] 3
     [echo] 1
     [echo] 2
     [echo] 3
     [echo] 4 5

BUILD SUCCESSFUL

Forking Groovy

Since 1.5.7 and 1.6-beta-2, <groovy> also supports a fork="true" attribute. In fact, many of the attributes from the <java> Ant task are supported. More details to come ...

More examples

Labels

 
(None)
  1. Apr 24, 2007

    Peter Kahn says:

    FYI, at the time the groovy script is executed, any classes that it references m...

    FYI, at the time the groovy script is executed, any classes that it references must be findable in individual groovy files or class files along the classpath.  If they cannot be located you may wind up with a java.lang.StackOverflowError exception. 

    I had a couple of classes in a single groovy file.  When ant executed my <groovy> block which invoked one of the classes from the groovy file it failed.

    However, one-class-one-file is but one way to solve this problem.  It is also possible to solve this by using *<groovyc>*to build the groovy files (which creates one class file for each class) and then point the class path at groovyc output folder (or you can jar them up).

  2. Jan 03, 2008

    Jeff Schnitter says:

    Is there a way to specify the Java path to use in the groovy task, without needi...

    Is there a way to specify the Java path to use in the groovy task, without needing to rely on Java being in the PATH or having JAVA_HOME set?

    I have an Ant script that needs to call another ant script, in which there is a groovy task defined.  I never want my build to be dependent on something defined in the Environment.  I want full control in my script.  I was hoping that  I could use something like the executable attribute that can be used for the javac Ant task.