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 |
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 |
project |
the current ant project |
properties |
a |
target |
the owning target that invoked this groovy script |
task |
the wrapping task, can access anything needed in |
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