Mixing Ant and Gradle scripts

Gradle is an ever-growing, innovative build system that gets new capabilities every day.
This article shows how to import existing Ant tasks into a Gradle build script. This functionnality is only available in the latest development branch on Gradle’s SCM.

You might say that using Ant tasks in Gradle is no big news : we can already mport them through Groovy’s AntBuilder and Gradle’s custom DSL, like this :

  1. task viewProperties << {
  2. ant.echoproperties(destfile:'dump-properties.txt', format:'text')
  3. }

What is really new and interesting is that Gradle can now import a whole Ant script ; each Ant target is then automatically converted to a Gradle task.

The following Ant script (with its related properties file) will be taken as an example throughout this article :

  1. <project name="proj-ex1">
  2.  
  3. <property file="project.properties"/>
  4.  
  5. <path id="compile.classpath">
  6. <fileset dir="${lib.dir}">
  7. <include name="**/*.jar"/>
  8. </fileset>
  9. </path>
  10.  
  11. <target name="clean">
  12. <delete dir="${dist.dir}"/>
  13. <delete dir="${distrib.dir}"/>
  14. </target>
  15.  
  16. <target name="init" depends="clean">
  17. <mkdir dir="${dist.dir}"/>
  18. <mkdir dir="${distrib.dir}"/>
  19. </target>
  20.  
  21. <target name="compile" depends="init">
  22. <javac srcdir="${src.dir}" destdir="${dist.dir}">
  23. <classpath refid="compile.classpath"/>
  24. </javac>
  25. </target>
  26.  
  27. </project>
 name=example1 lib.dir=lib src.dir=src/main/java dist.dir=build distrib.dir=distrib destfile=${dist.dir}/${name}.jar 

This script defines the following lifecycle : « clean->init->compile ».

Importing an Ant script

The new Gradle plugin allows a deep interaction with the Ant tasks defined in the imported script. Gradle tasks can even inherit from Ant targets and override their properties.

Let’s import and run our example Ant script through Gradle :

  1. usePlugin 'ant'
  2. importAntBuild 'build.xml'

The following command will compile the project and execute the « clean->init->compile » target chain :

  1. gradle compile

Task management

Task overriding

It is very easy to override an Ant target from Gradle.
The « compile » target (declared in the Ant script) can be redefined like this :

  1. compile <<{
  2. println "Compiling the source code"
  3. }
Task inheritance

You can even create a Gradle task that inherits from an Ant task :

  1. task jar (dependsOn: 'compile')<<{
  2. ant.jar(destfile:project.ant.destfile, basedir:project.ant."dist.dir")
  3. }

This defines a « jar » task that packages the application, and is executed only if the ant-defined « compile » task completes successfully.

Task inheritance, the other way

It is also possible to have an Ant task depend on a Gradle task.
Here, the Ant « dist » target depends on the « jar » and « sources » Gradle tasks…

  1. <target name="dist" depends="jar, sources">
  2. <copy file="${destfile}" todir="${distrib.dir}"/>
  3. </target>

…which are defined in the following Gradle script :

  1. task sources(type:Zip) {
  2. destinationDir= new File('C:/dev/gradle/ant/build')
  3. zipFileSet(dir:'src'){
  4. include('**/*.*')
  5. }
  6. baseName='titi'
  7. }

The whole « clean->init->compile->jar->sources->dist » build chain can now be executed by the single command :

  1. gradle dist

Final words

You may have noticed that the Ant script cannot be executed on its own any more, because the « jar » and « sources » targets don’t exist.
A simple workaround is to defined those tasks as empty tasks (that will be overriden in Gradle) : the script is now valid again and can be executed.

  1. <target name="jar" depends="compile"/>
  2.  
  3. <target name="sources"/>
  4.  
  5. <target name="dist" depends="jar, sources">
  6. <copy file="${destfile}" todir="${distrib.dir}"/>
  7. </target>

Finally, let’s override the empty tasks in our Gradle script :

  1. jar << {
  2. ant.jar(destfile:project.ant.destfile, basedir:project.ant."dist.dir")
  3. }
  4.  
  5. task myZipTask(type:Zip) {
  6. destinationDir= new File('C:/dev/gradle/ant/build')
  7. zipFileSet(dir:'src'){
  8. include('**/*.*')
  9. }
  10. baseName='foo'
  11. }
  12.  
  13. sources << {
  14. myZipTask.execute()
  15. }

Conclusion

This new functionality enables Gradle to be used as a complementary build system, that can be plugged in on a preexisting Ant infrastructure. With all its qualities, no doubt Gradle will see its adoption in the enterprise space grow massively in the forthcoming months.

For more information, please refer to the official documentation available on the Gradle project’s website.

Click on this link for a french version of this post.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

%d blogueurs aiment cette page :