1. <groovy>

Here we describe an Ant task for using Groovy from within an Ant build file. You may also be interested in Ant’s built-in script task which supports Groovy and other languages, or AntBuilder which lets you write Ant build scripts in Groovy rather than XML.

Executes a series of Groovy statements from Apache Ant. Statements can either be read in from a resource or as direct text between the enclosing Groovy tags.

2. Required taskdef

Assuming all the groovy jars you need are in my.classpath (this will be groovy-VERSION.jar, groovy-ant-VERSION.jar plus any modules and transitive dependencies you might be using) you will need to declare this task at some point in the build.xml prior to the groovy task being invoked.

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

You can simply place statements between the groovy tags like this:

<groovy>
...
</groovy>

Or you can supply the Groovy source script as a resource. You can specify the pathname using the src attribute like this:

<groovy src="/some/path/MyGroovyScript.groovy" otherAttributes="...">

Or as a nested fileset like this (though the fileset definition is expected to select just one file):

<groovy>
    <fileset file="MyGroovyScript.groovy"/>
</groovy>

Or as a nested single element resource collection which could look like any of these:

<groovy>
    <file file="MyGroovyScript.groovy"/>
</groovy>

<groovy>
    <url url="https://some.domain/some/path/to/MyGroovyScript.groovy"/>
</groovy>

<groovy>
    <javaconstant name="some.packagename.SomeClass.MY_CODE_FRAGMENT"/>
</groovy>

You may also supply a filter chain like this:

<groovy>
    <fileset file="MyGroovyScript.groovy"/>
    <!-- take 5 lines after skipping 18 lines, just as an example -->
    <filterchain>
        <headfilter lines="5" skip="18"/>
    </filterchain>
</groovy>

You might need to use the contextClassLoader attribute (see below) if any of your modules load services via the classpath, e.g. groovy-json.

3. <groovy> attributes

Attribute Description Required

contextClassLoader

If enabled, the contextClassLoader to be set with the classLoader of the shell used to run the script. Not used if fork is true.

No

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

output

Set the output file; defaults to the Ant log.

No

append

If enabled and output is to a file, append to existing file rather than overwrite. Defaults to false.

No

fork

If enabled the script will be executed in a forked JVM process (disabled by default).

No

scriptBaseClass

The name of the base class for scripts.

No

indy

If enabled the script will be executed with invokedynamic (disabled by default).

No

parameters

Generates metadata for reflection on method parameter names on JDK 8 and above. Defaults to false.

No

useGroovyShell

If enabled a new GroovyShell is used to run the script. Special variables won’t be available but you don’t need Ant in the classpath. Defaults to false.

No

includeAntRuntime

If enabled the system classpath will be included on the classpath when forking. Defaults to true.

No

stacktrace

If enabled a stacktrace will be reported if an error occurs during compilation. Defaults to false.

No

configScript

Sets the configuration script for the groovy compiler configuration.

No

4. Parameters specified as nested elements

4.1. <classpath>

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

4.2. <arg>

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

5. Available bindings

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

Name Description

args

command line arguments, if any

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

6. 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>

Run a script:

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

Find all 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>

Calling out to a web service from your Ant script:

<?xml version="1.0" encoding="UTF-8"?>
<project name="SOAP example" default="main" basedir=".">
    <property environment="env"/>
    <property name="celsius" value="0"/>
    <target name="main">
        <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
            <classpath>
                <fileset dir="${env.GROOVY_HOME}" includes="lib/groovy-*.jar,lib/ivy*.jar"/>
            </classpath>
        </taskdef>
        <groovy>
            @Grab('org.codehaus.groovy.modules:groovyws:0.5.1')
            import groovyx.net.ws.WSClient
            def url = 'http://www.w3schools.com/webservices/tempconvert.asmx?WSDL'
            def proxy = new WSClient(url, this.class.classLoader)
            proxy.initialize()
            ant.echo "I'm freezing at ${properties.celsius} degrees Celsius"
            properties.result = proxy.CelsiusToFahrenheit(properties.celsius)
        </groovy>
        <antcall target="results"/>
    </target>
    <target name="results">
        <echo message="I'm freezing at ${result} degrees Fahrenheit"/>
    </target>
</project>

Which will output the following (along with some informational messages):

main:
     ...
     [echo] I'm freezing at 0 degrees Celsius
results:
     [echo] I'm freezing at 32 degrees Fahrenheit

BUILD SUCCESSFUL

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>

Output:

Buildfile: build.xml

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

BUILD SUCCESSFUL