If you have invested a lot of time in setting up a build with Ant, the switch to Gradle might sound scary. In that case, Gradle cannot only execute Ant tasks, it can also expand them. This means you can migrate from Ant to Gradle in smaller steps, instead of spending several days on converting your entire build configuration.
Gradle uses Groovy's AntBuilder for the Ant integration. The AntBuilder enables you to execute any standard Ant task, your own custom Ant tasks, and entire Ant builds. It also makes it possible to define Ant properties in your Gradle build configuration.
Running a standard Ant task from Gradle is straightforward. You just need to prepend the task name with ant.
and everything works out of the box. For example, to create an archive, you can use this task:
task archive << { ant.echo 'Ant is archiving...' ant.zip(destfile: 'archive.zip') { fileset(dir: 'zipme') } }
The task is defined in Gradle, but makes use of two Ant tasks, echo
and zip
.
Of course you should always consider the Gradle alternatives for the standard Ant tasks. To create an archive like in the previous example, you can define a Gradle task that can handle this for you:
task gradleArchive(type:Zip) << { from 'zipme/' archiveName 'grarchive.zip' }
The task for the Gradle-based archive is more concise and easy to understand. Because it does not need to go through the AntBuilder, it is also slightly faster than using the Ant tasks.
If you have created an Ant script to build your app, you can import the whole build configuration, using ant.importBuild
. All Ant targets are then automatically converted to Gradle tasks that you can access by their original name.
For example, take the following Ant build file:
<project> <target name="hello"> <echo>Hello, Ant</echo> </target> </project>
You can import this build file into your Gradle build like this:
ant.importBuild 'build.xml'
This will expose the hello task to your Gradle build, so you can execute it like a regular Gradle task, and it will print out Hello, Ant
:
$ gradlew hello :hello [ant:echo] Hello, Ant
Because the Ant task is converted to a Gradle task, you can also extend it using the doFirst
and doLast
blocks, or the <<
shortcut. For example, you can print another line to the console:
hello << { println 'Hello, Ant. It's me, Gradle' }
If you execute the hello
task now, it looks like this:
$ gradlew hello :hello [ant:echo] Hello, Ant Hello, Ant. It's me, Gradle
You can also depend on tasks imported from Ant, just like you usually would. For example, if you want to create a new task that depends on the hello task, you can simply do this:
task hi(dependsOn: hello) << { println 'Hi!' }
Using dependsOn
makes sure the hello
task gets triggered when executing the hi
task:
$ gradlew intro :hello [ant:echo] Hello, Ant Hello, Ant. It's me, Gradle :hi Hi!
If you need to, you can even make an Ant task depend on a Gradle task. To accomplish this, you need to add the depends
attribute to the task in the build.xml
file, like this:
<target name="hi" depends="intro"> <echo>Hi</echo> </target>
If you have a big Ant build file, and you want to make sure none of the task names overlap, you can rename all the Ant tasks on import, using this code snippet:
ant.importBuild('build.xml') { antTargetName -> 'ant-' + antTargetName }
If you decide to rename all the Ant tasks, keep in mind that if you have an Ant task that depends on a Gradle task, then that Gradle task needs to be prefixed as well. Otherwise, Gradle will not be able to find it and throw an UnknownTaskException
.
Gradle and Ant cannot only share tasks, but you can also define properties in Gradle that can be used in your Ant build files. Consider this Ant target, which prints out a property called version
:
<target name="appVersion"> <echo>${version}</echo> </target>
You can define the version property in the Gradle build configuration by prepending the property name with ant.
, just like with tasks. This is the shortest way to define an Ant property:
ant.version = '1.0'
Groovy hides a lot of the implementation here. If you write the property definition in full, it looks like this:
ant.properties['version'] = '1.0'
Executing the version
task will do exactly what you would expect, namely printing out 1.0
to the console:
$ gradlew appVersion :appVersion [ant:echo] 1.0
Having deep Ant integration in Gradle makes it a lot easier to transition from Ant-based builds to Gradle, and you can do it at a pace that you are comfortable with.