Notes on using Groovy in Ant Scriptdef

Ant build scripts can define new tasks in a script language using ‘scriptdef‘. The following are a few notes I’m collecting on using the Groovy language with scriptdef.

Since I don’t do this often I have to re-read the info on how to use it. Thus, I’d thought I create a post where I collect this info. for future use.

Groovy Ant task
Groovy already supplies a Groovy Ant script task: org.codehaus.groovy.ant.Groovy.
To use, you define declare it in the Ant script:
[sourcecode language=”xml”]
<path id="libs">
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>

<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="libs"/>
[/sourcecode]

Then use it:
[sourcecode language=”xml”]
<groovy>
println "Hello World"
</groovy>
[/sourcecode]

The bindings supplied with the Groovy Ant task are:

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

ScriptDef task
The ScriptDef task in Ant just allows the creation of custom tasks using a scripting language, unlike the Taskdef task. I’m sure there are other approaches, perhaps for many situations, a taskdef that uses the groovy task within it is doable.

Example

[expand title=”Listing 1, example ant script”]
[sourcecode language=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<project name="project" default="demo1" basedir=".">
<path id="libs">
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>

<!– Groovy library –>
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="libs"/>

<scriptdef name="groovyInfo" language="groovy"
classpathref="libs"
src="src/ScriptInfo.groovy">

<attribute name="attr1"/>
<element name="fileset" type="fileset"/>

</scriptdef>

<!– target: default –>
<target name="demo1" description="description">

<groovyInfo attr1="anAttrib">
<fileset dir="src"/>
<fileset dir="lib"/>
</groovyInfo>

</target>

</project>
[/sourcecode]
[/expand]

Hmmm. I’m thinking of perhaps creating a Groovy utility that one can just use in a Scriptdef to give the same bindings as the Groovy Ant task.

[expand title=”Listing 1, ScriptInfo.groovy source”]
[sourcecode language=”groovy”]
println "project: ${project ?: ”}"
println "properties: ${properties ?: ”}"
println "Object:\n ${dump()}"
println "The binding:\n ${properties[‘binding’].dump()}"

int indent = 1
println "\n\n\nProperties"
binding.getProperties().each{ p ->
if(p.value instanceof Map){
println ‘ ‘ * indent + p.key + ":"
indent ++
p.value.each{ entry ->
println ‘ ‘ * indent + "${entry}"
}
indent–
}else{
println "${‘ ‘ * indent}prop: $p"
}
}

println "\nDirect access of attribute"
println "\tattribute attr1=" + binding.attributes.get(‘attr1’)

println "Direct access to elements"
elements.fileset.each{ fs ->
fs.each{
println "\t$it"
}
}
[/sourcecode]
[/expand]

The result of running the above Ant script is shown below:
[sourcecode]
demo1:
project: org.apache.tools.ant.Project@5213fce3
properties: [class:class Script1, binding:org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$1@11a7a000]
Object:
<Script1@4d129d08 binding=org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$1@11a7a000>
The binding:
<org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$1@11a7a000 val$ctx=javax.script.SimpleScriptContext@668ce272 this$0=org.codehaus.groovy.jsr223.GroovyScriptEngineImpl@2b66def7 variables=[project:org.apache.tools.ant.Project@5213fce3, context:javax.script.SimpleScriptContext@668ce272, self:org.apache.tools.ant.taskdefs.optional.script.ScriptDefBase@6eb84063, attributes:[attr1:anAttrib], elements:[fileset:[BindTest.class;BindTest.groovy;ScriptInfo.groovy, groovy-all-2.2.1.jar]], out:java.io.PrintWriter@28b5c5f]>

Properties
prop: class=class org.codehaus.groovy.jsr223.GroovyScriptEngineImpl$1
variables:
project=org.apache.tools.ant.Project@5213fce3
context=javax.script.SimpleScriptContext@668ce272
self=org.apache.tools.ant.taskdefs.optional.script.ScriptDefBase@6eb84063
attributes={attr1=anAttrib}
elements={fileset=[BindTest.class;BindTest.groovy;ScriptInfo.groovy, groovy-all-2.2.1.jar]}
out=java.io.PrintWriter@28b5c5f

Direct access of attribute
attribute attr1=anAttrib
Direct access to elements
C:\Users\jbetancourt\workspace-4.3\ScriptdefInfo\src\BindTest.class
C:\Users\jbetancourt\workspace-4.3\ScriptdefInfo\src\BindTest.groovy
C:\Users\jbetancourt\workspace-4.3\ScriptdefInfo\src\ScriptInfo.groovy
C:\Users\jbetancourt\workspace-4.3\ScriptdefInfo\lib\groovy-all-2.2.1.jar
BUILD SUCCESSFUL
Total time: 1 second
[/sourcecode]

About Ant
Ant is the breakthrough build system for the Java platform. Since there are now many other build systems, such as Maven and Gradle, Ant could be seen as a legacy build system, in some sense. JSON and the resurgence of scripting languages is changing the view of an build language in XML.
From the Ant homepage:

“Apache Ant is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other. The main known usage of Ant is the build of Java applications. Ant supplies a number of built-in tasks allowing to compile, assemble, test and run Java applications. Ant can also be used effectively to build non Java applications, for instance C or C++ applications. More generally, Ant can be used to pilot any type of process which can be described in terms of targets and tasks. ”

About Groovy
From the Groovy home page we have:

  • is an agile and dynamic language for the Java Virtual Machine
  • builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk
  • makes modern programming features available to Java developers with almost-zero learning curve
  • provides the ability to statically type check and statically compile your code for robustness and performance
  • supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain
  • makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL
  • increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications
  • simplifies testing by supporting unit testing and mocking out-of-the-box
  • seamlessly integrates with all existing Java classes and libraries
  • compiles straight to Java bytecode so you can use it anywhere you can use Java

No, they didn’t pay me to advertise Groovy. 🙂

Further Reading

2 thoughts on “Notes on using Groovy in Ant Scriptdef”

Leave a Reply

Your email address will not be published. Required fields are marked *