February 18, 2019
Hot Topics:

Introduction to Custom Ant Tasks

  • September 7, 2006
  • By Rob Lybarger
  • Send Email »
  • More Articles »

Example Four: Getting and Setting Project Properties

Suppose you want to set a project-level property in your task that contains the output message instead of directly sending the message to the log() method. Because you have subclassed the Task class, you can call the getProject() to return a reference to the Project you are running under, and then you may call getProperty and setProperty on that Project reference. Consider this modified build.xml file:

<project name="demo" basedir="." default="demo">

   <taskdef resource="MyAntTasks.properties" classpath="mytasks.jar"/>

   <target name="demo">
      <helloworld name="Bob" property="greeting"/>
      <echo message="${greeting}"/>


I have added a property attribute to your custom task. To prove the property is indeed being set, I have also added a standard echo task to display the value of that property. (The standard Ant tasks tend to call the attribute "property" as I have done here.)

To support this, you must add a property instance variable and its corresponding getter/setter method to your class file (not shown, but see a preceding example for details or look at the downloadable files for this example). Then, you modify your execute method slightly:

/* Add 'private String property=null;' and implement
   its getter/setter methods normally*/

public void execute() throws BuildException {

   if (property==null || property.length() == 0) {
      log("Cannot set property as attribute was not given.",

   if (name != null && name.length() > 0) {
      Project project = getProject();
      String propertyValue = "Hello, "+name+"!";
      project.setProperty(property, propertyValue);
      log("Set property: " + property + " -> " + propertyValue,
   else {
        throw new BuildException("name attribute is required.");


Note that my approach implies the property attribute is optional: If it is not specified, an "ERROR" priority level message is generated and no further action takes place. (Note the 'return' statement.) This might not be a good idea in reality—you might choose, instead, to require the property attribute in the same manner that the name attribute is required (that is, by throwing a BuildException if it is omitted). The real change to pay attention to is the way you get a reference to your Project and then set a new property in it.

Important: Recall that, in Ant, property values are immutable!

Also note that I am sending a message at the "VERBOSE" priority level that tells you what property name is being set to what property value. This is mainly for behavioral consistency to the standard property task in Ant. To see it, remember to run Ant with the "-verbose" option. If you do, you should see this output:

...(verbose output info skipped)...

[helloworld] Set property: greeting -> Hello, Bob!
     [echo] Hello, Bob!

Total time: 0 seconds


This article has shown you how to create and use your own custom Ant tasks. A great deal of credit should be given to Ant's developers for making this as relatively easy as it is as well as the community of developers who have contributed to the standard task set. Although the manual that is included with Ant does touch on custom task creation, its examples and explanations leave a bit to be desired, in my opinion. With that being said, I hope this article has made things a bit easier to follow. Even though the running "Hello World" example is fairly simplistic, you should be able to see the power available: any code you can write in Java to accomplish some task can be turned into a custom Ant task with little effort. Extend the Task class, provide an execute() method, and package the code with a properties file for maximum ease of use.

What's Left?

A couple things haven't been shown in this article, and they both related to nesting information inside your task's element. First, I'll mention briefly the "public void addText(String text)" method, which your custom task inherits from the Task class. This lets you capture text you might put between the opening and closing tags of a custom task. (That is, "text nodes" in XML-speak.) I opted not to demonstrate this for a couple reasons: First, you should be able to work it out for yourself now, and second, property values are NOT automatically expanded in such text (although the Project class has some facilities to help you do this yourself).

The other more important thing that was not shown is how to handle nested elements. I will address this in a future article. Although the material is not necessarily more difficult than that in this article, I feel it does merit more focused attention. People who have dipped their toe into custom Ant tasks may also wonder about a "type" as opposed to a "task." Because a "type" really needs to be nested underneath another element to be of any real use, I'll again defer discussion to a future article. (The notion of "types" exists to provide helper elements that do not necessarily need to "execute()" anything, but which may nonetheless serve as helper to their parent element.)

Finally, I would like to mention that there is a set of Ant tasks available for your use by way of the "ant-contrib" SourceForge project. This adds some nice capabilities such as "if/then/else", "foreach", and even "try/catch" to your build.xml files. See the Resources section for a link.

Download the Code

You may download the code that accompanies the article here.


About the Author

Rob Lybarger is a software engineer who has been using Java for nearly a decade and using Ant since its earliest days. He has used various versions of Windows, various distributions of Linux, and, most recently, Mac OS X. Although knowing a wide array of software languages, the cross-platform nature of Java and Ant has proven to be a valuable combination for his personal and professional efforts.

Page 3 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date