Search code examples
antmulti-project

Ant optional classpath element


I have some modules and a main runnable project. I have common build file, and

build.common.xml

<target name="build" >
  <path id="libraries.classpath">
    <fileset dir="${lib.dir}" includes="*.jar" />
  </path>
  <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
    <classpath refid="libraries.classpath" />
    <classpath refid="modules.classpath" />
  </javac>
</target>

..and every module declares its own dependencies in their build.xml:

<path id="modules.classpath">
  <pathelement path="../ModuleA/${build.dir}" />
  ...
</path>

The problem is if there is no internal dependency I get the following exception: "Reference modules.classpath not found."

What is the solution for that? How could I declare an optional classpath element?

Note: If anybody want to suggest to create jars out of my modules, please justify this. I'm going to have 5-10 rapidly changing modules, and I don't want to do unnecesary steps in the build process.

Update: I extracted the build into two different targets and created a condition for them, but did not help (it echoes the 'false' and builds with module-dependencies):

<target name="build">
    <condition property="modules.classpath.set" else="false">
          <isset property="modules.classpath"/>
    </condition>

    <echo message="modules.classpath is set: ${modules.classpath.set} " />
    <antcall target="build-with-modules" />
    <antcall target="build-without-modules" />
</target>

<target name="build-with-modules" if="modules.classpath.set">
    <echo message="Building with module-dependencies" />
    <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
        <classpath refid="libraries.classpath" />
        <classpath refid="modules.classpath" />
    </javac>
</target>
<target name="build-without-modules" unless="modules.classpath.set">
        <echo message="Building with  no dependent modules" />
    <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
        <classpath refid="libraries.classpath" />
    </javac>
</target>

Solution

  • Condition isreference:

    Test whether a given reference has been defined in this project and - optionally - is of an expected type.

    So, try

    <condition property="modules.classpath.set" else="false">
        <isreference refid="modules.classpath"/>
    </condition>
    

    Also on that page, there is a link to a page that describes custom conditions. If none of the provided conditions meets your requirement, then just write one.

    Update:

    The logic of if and unless in <target> is to check if the property has been set -- for if, the target runs when the property has been set; for unless, the target runs when the property has NOT been set -- not the value of the property.

    I have never checked the code of the condition isreference, but I think maybe the else="false" should be removed.

    If removing that part still doesn't help, then you may need to use some embedded groovy or beanshell script, or write your own condition.