Gradle provides excellent integration with Ant. You can use individual Ant tasks or entire Ant builds in your Gradle builds. In fact, you will find that it's far easier and more powerful using Ant tasks in a Gradle build script, than it is to use Ant's XML format. You could even use Gradle simply as a powerful Ant task scripting tool.
Ant can be divided into two layers. The first layer is the Ant language. It provides the syntax for the
build.xml
file, the handling of the targets, special constructs like macrodefs, and so on.
In other words, everything except the Ant tasks and types. Gradle understands this language, and allows you to
import your Ant build.xml
directly into a Gradle project. You can then use the targets of
your Ant build as if they were Gradle tasks.
The second layer of Ant is its wealth of Ant tasks and types, like javac
,
copy
or jar
. For this layer Gradle provides integration
simply by relying on Groovy, and the fantastic AntBuilder
.
Finally, since build scripts are Groovy scripts, you can always execute an Ant build as an external process.
Your build script may contain statements like:"ant clean compile".execute()
.
[8]
You can use Gradle's Ant integration as a path for migrating your build from Ant to Gradle. For example, you could start by importing your existing Ant build. Then you could move your dependency declarations from the Ant script to your build file. Finally, you could move your tasks across to your build file, or replace them with some of Gradle's plugins. This process can be done in parts over time, and you can have a working Gradle build during the entire process.
In your build script, a property called ant
is provided by Gradle. This is a reference
to an AntBuilder
instance. This AntBuilder
is used to
access Ant tasks, types and properties from your build script. There is a very simple mapping from Ant's
build.xml
format to Groovy, which is explained below.
You execute an Ant task by calling a method on the AntBuilder
instance. You use the task
name as the method name. For example, you execute the Ant echo
task by calling the
ant.echo()
method. The attributes of the Ant task are passed as Map parameters to the
method. Below is an example of the echo
task. Notice that we can also mix
Groovy code and the Ant task markup. This can be extremely powerful.
Example 17.1. Using an Ant task
build.gradle
task hello << {
String greeting = 'hello from Ant'
ant.echo(message: greeting)
}
Output of gradle hello
> gradle hello :hello [ant:echo] hello from Ant BUILD SUCCESSFUL Total time: 1 secs
You pass nested text to an Ant task by passing it as a parameter of the task method call. In this example, we
pass the message for the echo
task as nested text:
Example 17.2. Passing nested text to an Ant task
build.gradle
task hello << {
ant.echo('hello from Ant')
}
Output of gradle hello
> gradle hello :hello [ant:echo] hello from Ant BUILD SUCCESSFUL Total time: 1 secs
You pass nested elements to an Ant task inside a closure. Nested elements are defined in the same way as tasks, by calling a method with the same name as the element we want to define.
Example 17.3. Passing nested elements to an Ant task
build.gradle
task zip << { ant.zip(destfile: 'archive.zip') { fileset(dir: 'src') { include(name: '**.xml') exclude(name: '**.java') } } }
You can access Ant types in the same way that you access tasks, using the name of the type as the
method name. The method call returns the Ant data type, which you can then use directly in your build script. In the
following example, we create an Ant path
object, then iterate over the contents of it.
Example 17.4. Using an Ant type
build.gradle
task list << { def path = ant.path { fileset(dir: 'libs', includes: '*.jar') } path.list().each { println it } }
More information about AntBuilder
can be found in 'Groovy in Action' 8.4 or at the
Groovy Wiki
To make custom tasks available in your build,
you can use the taskdef
(usually easier) or typedef
Ant task,
just as you would in a build.xml
file. You can then refer to the custom Ant task as you
would a built-in Ant task.
Example 17.5. Using a custom Ant task
build.gradle
task check << { ant.taskdef(resource: 'checkstyletask.properties') { classpath { fileset(dir: 'libs', includes: '*.jar') } } ant.checkstyle(config: 'checkstyle.xml') { fileset(dir: 'src') } }
You can use Gradle's dependency management to assemble the classpath to use for the custom tasks. To do this, you need to define a custom configuration for the classpath, then add some dependencies to the configuration. This is described in more detail in Section 51.4, “How to declare your dependencies”.
Example 17.6. Declaring the classpath for a custom Ant task
build.gradle
configurations { pmd } dependencies { pmd group: 'pmd', name: 'pmd', version: '4.2.5' }
To use the classpath configuration, use the asPath
property of the custom configuration.
Example 17.7. Using a custom Ant task and dependency management together
build.gradle
task check << { ant.taskdef(name: 'pmd', classname: 'net.sourceforge.pmd.ant.PMDTask', classpath: configurations.pmd.asPath) ant.pmd(shortFilenames: 'true', failonruleviolation: 'true', rulesetfiles: file('pmd-rules.xml').toURI().toString()) { formatter(type: 'text', toConsole: 'true') fileset(dir: 'src') } }
You can use the ant.importBuild()
method to import an Ant build into your Gradle
project. When you import an Ant build, each Ant target is treated as a Gradle task. This means you can
manipulate and execute the Ant targets in exactly the same way as Gradle tasks.
Example 17.8. Importing an Ant build
build.gradle
ant.importBuild 'build.xml'
build.xml
<project> <target name="hello"> <echo>Hello, from Ant</echo> </target> </project>
Output of gradle hello
> gradle hello :hello [ant:echo] Hello, from Ant BUILD SUCCESSFUL Total time: 1 secs
You can add a task which depends on an Ant target:
Example 17.9. Task that depends on Ant target
build.gradle
ant.importBuild 'build.xml' task intro(dependsOn: hello) << { println 'Hello, from Gradle' }
Output of gradle intro
> gradle intro :hello [ant:echo] Hello, from Ant :intro Hello, from Gradle BUILD SUCCESSFUL Total time: 1 secs
Or, you can add behaviour to an Ant target:
Example 17.10. Adding behaviour to an Ant target
build.gradle
ant.importBuild 'build.xml' hello << { println 'Hello, from Gradle' }
Output of gradle hello
> gradle hello :hello [ant:echo] Hello, from Ant Hello, from Gradle BUILD SUCCESSFUL Total time: 1 secs
It is also possible for an Ant target to depend on a Gradle task:
Example 17.11. Ant target that depends on Gradle task
build.gradle
ant.importBuild 'build.xml' task intro << { println 'Hello, from Gradle' }
build.xml
<project> <target name="hello" depends="intro"> <echo>Hello, from Ant</echo> </target> </project>
Output of gradle hello
> gradle hello :intro Hello, from Gradle :hello [ant:echo] Hello, from Ant BUILD SUCCESSFUL Total time: 1 secs
There are several ways to set an Ant property, so that the property can be used by Ant tasks. You can
set the property directly on the AntBuilder
instance. The Ant properties are also
available as a Map which you can change. You can also use the Ant property
task.
Below are some examples of how to do this.
Example 17.12. Setting an Ant property
build.gradle
ant.buildDir = buildDir ant.properties.buildDir = buildDir ant.properties['buildDir'] = buildDir ant.property(name: 'buildDir', location: buildDir)
build.xml
<echo>buildDir = ${buildDir}</echo>
Many Ant tasks set properties when they execute. There are several ways to get the value of these properties.
You can get the property directly from the AntBuilder
instance. The Ant properties are
also available as a Map. Below are some examples.
Example 17.13. Getting an Ant property
build.xml
<property name="antProp" value="a property defined in an Ant build"/>
build.gradle
println ant.antProp
println ant.properties.antProp
println ant.properties['antProp']
There are several ways to set an Ant reference:
Example 17.14. Setting an Ant reference
build.gradle
ant.path(id: 'classpath', location: 'libs') ant.references.classpath = ant.path(location: 'libs') ant.references['classpath'] = ant.path(location: 'libs')
build.xml
<path refid="classpath"/>
There are several ways to get an Ant reference:
Example 17.15. Getting an Ant reference
build.xml
<path id="antPath" location="libs"/>
build.gradle
println ant.references.antPath
println ant.references['antPath']
The Ant integration is provided by AntBuilder
.
[8] In Groovy you can execute Strings. To learn more about executing external processes with Groovy have a look in 'Groovy in Action' 9.3.2 or at the Groovy wiki