0

I have a build.xml which looks like this

<target name="foo">
    <subant failonerror="false" target="p1">
        <fileset dir="." includes="build.xml"/>
    </subant>
    <subant failonerror="false" target="p2">
        <fileset dir="." includes="build.xml"/>
    </subant>
    <subant failonerror="false" target="p3">
        <fileset dir="." includes="build.xml"/>
    </subant>
</target>

When I do ant foo all the subants run simultaneosly. How do I make them run sequentially p1,p2,p3.

David W.
  • 105,218
  • 39
  • 216
  • 337
jacksparrow007
  • 1,298
  • 4
  • 19
  • 30

2 Answers2

5

Is this part of your build.xml file?

Usually, <subant/>, and <antcall/> tasks are a sign that the developer who created the build.xml does not understand Ant.

Ant is not a programming language like Python, Java, C, etc. It is a dependency matrix language. That is, you give it targets to build, and instructions on what to build. For example, you might have a target named jar that builds your Jar file. This tasks consists mainly of the <jar> command.

What you do is say what your jar command depends upon. For example, it probably depends upon you compiling the code. Therefore, you say it depends upon your compile target. The compilation may require both to build the classpath from the ivy.xml file, and turning the WSDL files into Java code to compile.

However, before you can create your classpath from your ivy.xml file, you must resolve it. And, before you turn your WSDL files into Java code, you want to fetch the latest versions of the WSDL from the project's website.

I don't have to ask Ant to do any of this. All I ask it to do is to build the Jar, and Ant figured out what it needs to do in order to build the jar. I have given up my programmer's mindset of telling Ant each and every step it must take to do a particular task, and I have to trust Ant to figure out what it needs to do and in what order.


You say you want these tasks to run in a particular order. You are bringing the wrong mindset to Ant, and if this foo target is an attempt to force the order, it's the wrong way.

Ask yourself what you want to really do. No, you don't want to build p1, p2, p3 in that order.

What you probably want to do is build whatever p3 builds. Maybe this is a jar or a war. Maybe this is a deployment of a war or ear to your website. That's what you really, really want to do. You don't care if you need to run p2 or p1 first, or whether p1 or p2 has to get executed first. Give up the concept of telling Ant how to do every single step.

Now, in order for your build.xml to execute the target p3 (deploying your war), it has to first execute the target p2 (building the war to deploy). That's a dependency on p3.

Now, maybe for the p2 target to be executed, it first has to run the p1 task (compile the Java code to create the classes your war needs). This is a dependency on the p2 task.

Here's a new simple build.xml that shows this dependency tree. Note I don't use <antcall>, <ant> or <subant> tasks. I merely depend upon Ant to figure out what to do on its own.

<project>
     <target name="p1">
         <echo>Running P1: Building the class files from the Java source.</echo>
     </target>
     <target name="p2"
         depends="p1">
         <echo>Running P2: Building the war we're going to deploy.</echo>
     </target>
    <target name="p3"
         depends="p2">
        <echo>Running P3: Deploying the war.</echo>
     </target>
</project>

Now I'll run Ant specifying the target I really want to accomplish:

$ ant p3
Buildfile: /Users/david/build.xml

p1:
     [echo] Running P1: Building the class files from the Java source.

p2:
     [echo] Running P2: Building the war we're going to deploy.

p3:
     [echo] Running P3: Deploying the war.

BUILD SUCCESSFUL

Notice that this did run p1, p2, and p3 in that order. However, nowhere in this file I actually stated that I wanted this done, and I really don't care. I just want to run p3. Ant figured out what targets it needs to run based upon the dependency tree.

David W.
  • 105,218
  • 39
  • 216
  • 337
  • What if I want p3 to run even if p1 and p2 fail? – jacksparrow007 Nov 20 '13 at 17:06
  • 1
    Ant builds fail immediately upon any task failing. Even if you put all the tasks in a single target, you'll get an immediate failure if `p1` or `p2` fail. Some tasks can be configured to continue by setting a parameter `failonerror` in that task to _false_. If you do that, the build will continue. Look at Antcontrib's [TryCatch](http://ant-contrib.sourceforge.net/tasks/tasks/trycatch.html) task to get around this issue with tasks that cannot be configured not to fail on error. – David W. Nov 20 '13 at 17:11
  • Thanks, Is there a reason why it is running the subants simultaneosly in my case? Is that how subant is supposed to work? – jacksparrow007 Nov 20 '13 at 17:32
  • If those sub ants are running tasks that run in the background (possible with ``, then one will fire up after another without the first one quitting. There's also a [Parallel](http://ant.apache.org/manual/Tasks/parallel.html) task, but I don't see that happening here. – David W. Nov 20 '13 at 18:07
  • @DavidW. +1 for clearify Ant's philosophy. Actually `` is provided for the ability to invoke multiple build files of sub-projects in a project. The example here is more like a "hack" -- in another Q&A, the OP uses "depends", but he wants the target still to run even if the dependency task fails without using ant-contrib's ``. Actually it doesn't make sense that one wants a target to run even if its dependencies fail. – Dante WWWW Nov 21 '13 at 05:33
1

Looks like sequential task does what you want. Example:

<target name="default">
    <sequential>
        <echo message="111"/>
        <echo message="222"/>
    </sequential>
</target>

also you may specify multiple targets in depends like <target name="t0" depends="t1,t2,t3">

Sergey Fedorov
  • 2,169
  • 1
  • 15
  • 26