This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Ant, Maven and Other Build Tools and the fly likes Executing multiple targets in subprojects Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Engineering » Ant, Maven and Other Build Tools
Bookmark "Executing multiple targets in subprojects" Watch "Executing multiple targets in subprojects" New topic
Author

Executing multiple targets in subprojects

Rob Williams
Greenhorn

Joined: Jul 22, 2005
Posts: 6
I have an issue with managing a multiple project build. Allow me to provide some context first.

I have a system of projects managed by an Ant build process consisting of multiple levels of Ant projects (Ant build scripts). A root Ant script invokes the subproject Ant scripts in the proper dependency order, down through multiple levels of subprojects.

As Ant is reinvoked for each subproject (via the subant task), the same target is invoked as for the calling project, all the way across and down the project tree.

Here is an example of a typical system file structure:
Root
Build.xml - invokes B/Build.xml, C/Build.xml, A/Build.xml
A
Build.xml
src
*.java
B
Build.xml - invokes B2/Build.xml, B1/Build.xml, B3/Build.xml
B1
Build.xml
src
*.java
B2
Build.xml
src
*.java
B3
Build.xml
src
*.java
C
Build.xml
src
*.java

I have a Windows script Ant.cmd that allows me to invoke Ant on the current directory, such that Ant executes the Build.xml script in that directory, which invokes the Build.xml scripts in the subdirectories as appropriate. So a typical invocation in a Windows command shell would be:

Ant clean build doc

Now, Ant's famous and desirable behavior is to evaluate the dependencies among the targets invoked on the command line, assemble an ordered list of targets to execute (including referenced dependencies but without duplicates), and then execute them in that order, WITHIN THAT SINGLE INVOCATION OF ANT.

But, when I invoke Ant on a Build.xml that invokes subprojects, my current Ant scripts result in A SEPARATE INVOCATION OF ANT FOR EACH TARGET ON EACH SUBPROJECT. This is due to the target dependencies being evaluated for the initial parent project (the one in the current directory), but the delegation occurs separately for each executed target (via subant). As a consequence, the subprojects are invoked repeatedly and many of their targets get executed repeatedly. The net effect is, for each subproject, as if I had instead entered the following into the Windows command shell:
Ant clean
Ant build
Ant doc

The problem with this behavior, of course, is that I do not get the same result from invoking a multi-target (e.g., clean build doc) build directly on a subproject as I do by invoking it on a parent project. In particular, the result is far less efficient since there are extra invocations of Ant on the subprojects and there are extra invocations of subproject targets.

However, the really big problem is that any property dependencies between subproject targets fail completely.

Consider a common practice for implementing debug versus release builds. The build target is typically implemented to default (via properties) to a debug compile. But, if you invoke the release target first, then those properties configure the compile for release mode instead. So
Ant build
gives you a debug compile, but
Ant release build
gives you a release compile since the release target sets the appropriate properties for release before the build target can set them for debug.

When invoking a subproject directly (in the current directory), this technique works as expected. But invoking a subproject through a parent project does not work because the release and build targets get executed IN SEPARATE INVOCATIONS OF ANT.

So, the solution is to get Ant to invoke a subproject with multiple targets ALL AT ONCE IN THE SAME INVOCATION OF ANT. But, it appears, none of the typical ways to invoke a subproject do this. The ant and subant tasks appear to only allow a single target in their target attributes, though I still need to do more thorough testing to be certain of this.

This results in my request: has anyone tackled this challenge of invoking multiple targets consistently down through a series of subprojects???

Thanks for your patience! ;^)


Rob Williams
Rob Williams
Greenhorn

Joined: Jul 22, 2005
Posts: 6
Oops, my file structure was not preserved in my initial post. Here it is again:

Root
---Build.xml - invokes B/Build.xml, C/Build.xml, A/Build.xml
---A
------Build.xml
------src
---------*.java
---B
------Build.xml - invokes B2/Build.xml, B1/Build.xml, B3/Build.xml
------B1
---------Build.xml
---------src
------------*.java
------B2
---------Build.xml
---------src
------------*.java
------B3
---------Build.xml
---------src
------------*.java
---C
------Build.xml
------src
---------*.java

Thanks.
Tim West
Ranch Hand

Joined: Mar 15, 2004
Posts: 539
First up, I haven't tackled this problem before, but here are my thoughts.

First, I'm somewhat amazed that you can't specify multiple targets like this:



...but you're right, it doesn't work. Perhaps you could define a meta-target in each build file:



On a side note, one of the examples in the subant task documentation describes a problem very similar to yours. I also found this article useful, though chances are you know this stuff already.

On property dependencies, does use of 'inheritall' and/or 'inheritrefs' not solve your problem?


-Tim
Rob Williams
Greenhorn

Joined: Jul 22, 2005
Posts: 6
Thanks for the reply. Yes, I am familiar with Ant's capabilities as documented at the links you provided. As the article says, doing a complex build such as mine is very much easier with the new capabilities of Ant 1.6.

I did indeed try creating composite targets such as rebuild = clean build, etc. Of course, this works in simple cases, but it does not scale. I don't want to have to create composite targets for every combination of my base targets and, if I did, I would encounter a combinatorial explosion of possiblities.

Ideally, I just want subant to handle multiple targets in a single invocation, just as though I were invoking Ant from the command line. Perhaps I need to post a request to their feature list.

Otherwise, it seems that my only solution is to reinvoke Ant via the exec task. Yuch!
Rob Williams
Greenhorn

Joined: Jul 22, 2005
Posts: 6
I forgot to address the inheritall and inheritrefs of the subant task. Yes, they could help to resolve part of my problem, and they may be able to be leveraged to solve all of it.

However, doing so would potentially involve a lot of extra properties with a lot of VERY careful management. The complexity seems prohibitive, and I think I would rather live with the inefficiencies instead. However, I have not yet tackled the integration of a release build into my new Ant infrastructure, or similarly complex processes that demand more property management.

We'll see...
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Executing multiple targets in subprojects
 
Similar Threads
help needed in ant
Can I debug in IDEA using ant to build?
conditional creating of a directory
Ant + Junit + Log4J Problem
How do I configure Ant? Is it a GUI interface?