3

I am trying to check if a property exists in ant with the following:

<target name="test">
    <property name="testproperty" value="1234567890"/>
    <if>
        <isset property="testproperty"/>
        <then>
            <echo message="testproperty exists"/>
        </then>
        <else>
            <echo message="testproperty does not exist"/>
        </else>
    </if>
</target>

The result is a failure with the message:

build.xml:536: Problem: failed to create task or type if
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.

I must be doing something wrong with isset as the following runs smoothly:

<target name="test">
    <property name="testproperty" value="1234567890"/>
    <echo message="'${testproperty}'"/>
</target>

Please advice :)

Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
Thanasis Pap
  • 2,031
  • 2
  • 17
  • 19

3 Answers3

9

The if task is not a standard ANT task. This is how conditional execution of a target works

<project name="demo" default="test">

  <target name="property-exists" if="testproperty">
    <echo message="testproperty exists"/>
  </target>

  <target name="property-no-exists" unless="testproperty">
    <echo message="testproperty does not exist"/>
  </target>

  <target name="test" depends="property-exists,property-no-exists">
  </target>

</project>
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • 2
    This++, ant-contrib will lead to tears. – thekbb Jun 11 '13 at 21:09
  • If ant contrib leads to tears… what will this lead to?Because this clearly communicates branching logic – Clintm Oct 20 '13 at 00:54
  • @ClintModien ANT was never designed as a scripting language and the above pattern illustrates the limits of core ANT. I think the designers of ANT assumed that complex logic would be implemented in Java and integrated as tasks. Ant-contrib's approach of bolting on programming contructs just seems alien to me. A better compromise IMHO is embed a scripting language like Groovy. See http://stackoverflow.com/questions/14500576/ant-if-else-condition/14509912#14509912 – Mark O'Connor Oct 20 '13 at 17:36
  • I would prefix the names of two supporting targets with "-" so that they cannot be called directly. – Alex May 01 '14 at 17:07
7

Apparently I was missing the ant-contrib jar file that can be found here:
http://ant-contrib.sourceforge.net/

Thanasis Pap
  • 2,031
  • 2
  • 17
  • 19
3

You've found the missing jar, now you need to define the tasks that use that jar. I would put the jar under the antlib/antcontrib directory inside your project. This way, others who download your project will have the needed jar.

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

If you use a lot of optional jar files, you might want to use namespaces:

 <project name="..." basedir="."  default="...."
    xmlns:ac="antlib://net/sf/antcontrib">

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

Now, when you use a antcontrib task, you have to preface it with ac:. This allows optional jars to be used without namespace collisions.

<target name="test">
    <property name="testproperty" value="1234567890"/>
    <ac:if>
        <isset property="testproperty"/>
        <then>
            <echo message="testproperty exists"/>
        </then>
        <else>
            <echo message="testproperty does not exist"/>
        </else>
    </ac:if>
</target>
David W.
  • 105,218
  • 39
  • 216
  • 337