Importing an ant buildfile multiple times

LMAX Exchange

According to the ant documentation:

It is possible to include the same file more than once by using different prefixes, it is not possible to import the same file more than once.

Unfortunately, it turns out this isn’t quite true. In most cases, ant will indeed ignore a request to import a file for the second time, so:

<import>
<file name="utils.xml"/>
<file name="utils.xml"/>
</import>

 

will only import utils.xml once. This is true even if there’s a chain of files being imported (so A imports B and C, then B imports C as well, C will only be imported once).

The problem arises if you’re importing the file via two different methods, you might wind up having it actually be imported twice. In my case I was loading build files from a zip archive (why is a long story that I should write up some time) and those build files references other files also within the zip file. So my main build file had:

<import>
<javaresource classpath="bootstrap.zip"
name="basic-build.xml"/>
</import>

Then basic-build.xml included another utils file from the same zip. Being the well-coded ant file that it is, basic-build.xml doesn’t depend on knowing where it’s actually located, so it imports the utils file via:

<import>
<url baseurl=${ant.file.basic-build}" relativePath="ivy-utils.xml"/>
</import>

This all works just fine. Then there came a requirement in our main build file to use one of the macros from ivy-utils.xml to set a version number before basic-build.xml was imported. So the main build file wound up with something like:

<import>
 <javaresource classpath="bootstrap.zip"
name="ivy-utils.xml"/> </import>
<!-- Do some stuff --> <import>
<javaresource classpath="bootstrap.zip"
name="basic-build.xml"/>
</import>

Suddenly the build started failing because ivy-utils.xml was being executed twice and attempting to redefine the ivy configuration which was explicitly disallowed.

Looking at the ant -debug output clearly showed the ivy-utils.xml was being imported twice and not skipped, and even that it came from exactly the same URL. It appears that resolving the same file using two different mechanisms (javaresource and url in this case) caused ant to believe they were different files.

The answer was fairly straight-forward, use url resources consistently when importing the files:

<import>
 <url url="jar:file:${ant.file}/bootstrap.zip!/ivy-utils.xml"/>
</import>
<!-- Do some stuff --> <import>
<url url="jar:file:${ant.file}/bootstrap.zip!/basic-build.xml"/>
</import>

Building a jar: URL like this is a little unpleasant but not unreasonable. Strictly we could have kept importing basic-build.xml using the javaresource approach but being consistent will save surprises in the future.

Any opinions, news, research, analyses, prices or other information ("information") contained on this Blog, constitutes marketing communication and it has not been prepared in accordance with legal requirements designed to promote the independence of investment research. Further, the information contained within this Blog does not contain (and should not be construed as containing) investment advice or an investment recommendation, or an offer of, or solicitation for, a transaction in any financial instrument. LMAX Group has not verified the accuracy or basis-in-fact of any claim or statement made by any third parties as comments for every Blog entry.

LMAX Group will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information. No representation or warranty is given as to the accuracy or completeness of the above information. While the produced information was obtained from sources deemed to be reliable, LMAX Group does not provide any guarantees about the reliability of such sources. Consequently any person acting on it does so entirely at his or her own risk. It is not a place to slander, use unacceptable language or to promote LMAX Group or any other FX and CFD provider and any such postings, excessive or unjust comments and attacks will not be allowed and will be removed from the site immediately.