views:

307

answers:

1

I've inherited an Ant build system that contains many resource set definitions like this:

<files id="app1.lib.jars">
  <include name="${java}/jre/lib/jsse.jar"/>
  <include name="${work.lib}/jtidy.jar"/>
  ...
</files>

<files id="app2.lib.jars">
  <include name="${work.lib}/itext.jar"/>
  <include name="${work.lib}/commons-httpclient.jar"/>
  ...
</files>

<files id="app3.lib.jars">
  <include name="${work.lib}/jdom.jar"/>
  <include name="${ant.lib}/ant.jar"/>
  ...
</files>

There are perhaps a dozen of these, and each can contain anywhere from 5 to 50 files. The problem is that I'm reworking this system to use Ivy for dependency management, and in the process some of the references now point to non-existent files. Unfortunately, Ant does not provide any help finding these bad pointers. When these resource collections are used to define a classpath any <include...> tags pointing to missing files are silently ignored.

I thought I could force an error by using the collections as the source of a <copy...>, but even with failonerror="true" it just ignored the bad references.

The command-line -v (verbose) and -d (debug) option didn't help either. The output acknowledged that some were missing but didn't actually show them

 [echo] app1.lib.jars
 [copy] C:\dev\src\tomcat6\work\java\jre\lib\jsse.jar omitted as C:\dev\src\tomcat6\work\verify\jsse.jar is up to date.
 [copy] C:\dev\src\tomcat6\work\lib\axis-ant.jar omitted as C:\dev\src\tomcat6\work\verify\axis-ant.jar is up to date.
 ...
 [copy] No sources found.
 [echo] app2.lib.jars
 ...

For a one-time solution I extracted all the filenames from the resource sets in the Ant file and compared that to a directory listing of the result of copying all the files (in Ant) into a temporary directory, after appropriate sorting.

Question: Is there a way to get Ant to tell me when a resource points to a missing file, preferably at the time the resource is defined?

+2  A: 

Here's an illustration of one method. Key points

  • Convert your files to filelists
  • Use a restrict to check for existence
  • Use a fail to error when something is missing

You'll need to add the "antlib:org.apache.tools.ant.types.resources.selectors" namespace to the project to use the resource selectors shown below. You'll hit snags with ant versions older than 1.7.0.

<project name="so" default="checkfiles" basedir="."
xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">

<filelist id="app1.lib.jars">
  <file name="${java}/jre/lib/jsse.jar"/>
  <file name="${work.lib}/jtidy.jar"/>
  ...
</filelist>

<restrict id="missing.app1.lib.jars">
  <filelist refid="app1.lib.jars"/>
  <rsel:not>
    <rsel:exists/>
  </rsel:not>
</restrict>

<property name="missing.files" refid="missing.app1.lib.jars" />
<fail message="These files are missing: ${missing.files}">
  <condition>
    <length string="${missing.files}" when="greater" length="0" />
  </condition>
</fail>
<pathconvert property="found.files" refid="app1.lib.jars" />
<echo message="Found files ${found.files}" />
martin clayton
+1 looks interesting. I'll try this tomorrow.
Jim Garrison
This solution is not optimal since I would prefer to use the newer resource containers (I find it strange that filelist and fileset haven't been refactored to subclass the containers). What I really want is an option that will tell Ant to issue warnings for missing files, but that doesn't appear to be available. Martin's answer looks like the best way to accomplish this for the time being.
Jim Garrison