Execute Ant task just if a condition is met

ant

Solution

An Ant target can have an optional `if` or `unless` clause. This means to execute the task only if the property is set, with an `if` clause, or is unset with the `unless` clause1. Interestingly, that `if` or `unless` clause is checked after any dependent task is first executed.

This means, you can do this in standard Ant as a way of executing an Ant task only if a particular condition is met:

 <target name="test.if.tomcat.is.running">
      <condition property="tomcat.running">
          <socket server="${tomcat.host}" port="${tomcat.port}"/> 
      </condition>
</target>

<target name="my.target"
    if="tomcat.running"
    depends="test.if.tomcat.is.running">
    <yaddah/>
    <yaddah/>
    <yaddah/>
</target>

You specify that you want Ant to execute Target `my.target`. Ant notices that `my.target` depends upon the `test.if.tomcat.is.running` target, and will execute that first. The `test.if.tomcat.is.running` task will set the `tomcat.running` property if Tomcat is actually running. Otherwise, that property is not set.

Finally, Ant will go back to the `my.target` target and see if the property `tomcat.running` is set, and will only execute the target `my.target` if it is set.

Or, you can use the Ant-contrib tasks which may make your entire build process easier to understand.

If you want to go the Ant-Contrib route, there's an easy way to setup Ant-Contrib, so the Ant-contrib jar is actually part of your project. If someone checks out your project from the version control system, they'll also get the Ant-contrib jar, and thus won't have to install Ant-Contrib themselves.

Download the Ant-Contrib jar, and put it into a directory in the root of your project called `antlib/ac`. The `antlib` can be used for all sorts of optional task jars such as Findbugs or PMD. Just put each optional Ant jar in their own directory under `antlib` (Like I put Ant-Contrib under the `ac` directory).

Then, in your `build.xml`, you specify the Ant-Contrib tasks this way:

<taskdef resource="net/sf/antcontrib/antlib.xml">
   <classpath>
       <fileset dir="${basedir}/antlib/ac"/>
   </classpath>
</taskdef>

Now, you can use the Ant-Contrib tasks without worrying whether or not they're installed on a particular machine or not. You checkout your project, and you have access to those tasks automatically.

1. That's right, the `if/unless` clause checks if a property is set and not `true`/`false` which can cause a lot of confusion. I've seen developers set a property to `false` or `no`, and then wonder why the target is actually executing since the `if` clause is set to false.

Problem

I need to execute an Ant task within a specific target only if a condition is met. I found a way to define the condition at the target level, but not at the task level. I have also found a contribution that implements an IF task. My question is, are you aware of any way to achieve this objective with standard Ant tasks? Longer explanation: I am trying to start Tomcat Server in case it is stopped. To detect if it is stopped I use following code: ``` <echo message="Checking whether Tomcat is running"/> <condition property="tomcat.running"> <socket server="${tomcat.host}" port="${tomcat.port}"/> </condition> ``` So my next task in this target, is an exec task that should be executed only if `${tomcat.running}` is false. And as I said, I don't want to add a single task in a target to use the unless property.

Original source