2

Is there a built-in way to get Ant to throw an error when a file included in the classpath task doesn't exist? My goal is for Ant to throw a build error when a compile target is called but the required libraries don't exist.

Here is an example from the build.xml file that includes the dependent libraries, however it doesn't throw an error when one of the libraries doesn't exist.

<target name="compile" description="Compiles the Java code" depends="init">
    <mkdir dir ="${build}/${module-package}" />
    <javac srcdir="${src}/main/${module-package}" 
           destdir="${build}" 
           includeantruntime="off"
           debug="true" 
           fork="true">

        <classpath>
            <fileset dir="${lib}" >
                <include name="joda-time/joda-time-2.1.jar" />
                <include name="jackson/jackson-core-lgpl-1.9.7.jar"/>
                <include name="jackson/jackson-mapper-lgpl-1.9.7.jar"/>
            </fileset>
        </classpath>
    </javac>
</target>  
Thomas
  • 1,103
  • 3
  • 13
  • 25
  • If a compiling-required library doesn't exist, won't the `javac` task itself fail the build? And, if the build doesn't fail, the library is not necessary. `javac` doesn't provide a function to ensure the files in the classpath exist or not; however, you can put the `fileset` outside, use `condition` and `fail` task to do the check and fail the build, and then invoke `javac`. – Dante WWWW Feb 05 '13 at 10:39
  • Yes, the javac task would fail, but it wouldn't be obvious which library was missing. I was hoping there was a better way to accomplish this rather than use condition and fail – Thomas Feb 05 '13 at 14:44
  • >the `javac` task would fail< Not always! Not when you include a jar which is never referred to explicitly in code. In my case, the usage was in the `web.xml` of my J2EE application, and it took me an afternoon of debugging that the jar wasn't being picked up because it was not present. An error message would have been immensely helpful to identify the problem. – Darshit Patel Nov 24 '21 at 10:56

1 Answers1

2

You could use the available task in ANT to check for the existence of classes you know should be present (provided by the jars).

<path id="compile.path">
    <fileset dir="${lib}" >
        <include name="joda-time/joda-time-2.1.jar" />
        <include name="jackson/jackson-core-lgpl-1.9.7.jar"/>
        <include name="jackson/jackson-mapper-lgpl-1.9.7.jar"/>
    </fileset>
</path>

<available classname="org.joda.time.DateTime" property="joda.present" classpathref="compile.path"/>
<available classname="org.codehaus.jackson.JsonFactory" property="jackson.present" classpathref="compile.path"/>

<target name="compile" description="Compiles the Java code" depends="init">
    <mkdir dir ="${build}/${module-package}" />

    <fail message="Joda time missing" unless="joda.present"/>
    <fail message="Jackson missing"   unless="jackson.present"/>

    <javac srcdir="${src}/main/${module-package}" 
           destdir="${build}" 
           includeantruntime="off"
           debug="true" 
           fork="true"
           classpathref="compile.path"
           />
</target>  
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • Is there a way to use this method so the error would show which jar specifically was missing, without having to repeat the jar filename in the `available` task? – Thomas Feb 06 '13 at 15:07
  • @ThomasRyabin not that I'm aware of. Would be a tricky feature to implement considering that in theory the same class could be packaged in more than one jar file on the classpath. Personally I solve this classpath management problem by using Apache ivy, and pull down all my dependencies from a Maven repository. – Mark O'Connor Feb 06 '13 at 15:31
  • Thanks @MarkO'Connor, this is a fantastic solution which helped in my case too. We usually use gradle, but in a legacy project i've been handed, its using ant. It was missing a lib and not obvious which internal project it is coming from. I've now updated the Ant build.xml to make things more obvious what is missing, and which project to fetch the lib from in future. However, I think I'll try converting to Maven in order to auto resolve dependancies, then just have this lib in our git repository – wired00 Mar 06 '16 at 00:21
  • @wired00 Converting ANT to Maven is no picnic (It would be simpler to switch to Gradle). For legacy builds I use the Apache ivy plugin. Adds dependency management to my ANT build. Finally ivy can deal with dependencies in a local dir much better than Maven can. For a taster see: http://stackoverflow.com/questions/14029777/is-there-any-ant-feature-that-copies-classpath-dependencies-to-web-inf-lib/14031439#14031439 and http://stackoverflow.com/questions/10175000/sample-example-which-explain-how-to-use-filesystem-resolver/10180491#10180491 – Mark O'Connor Mar 06 '16 at 04:08