First Ant build.xml file not compiling as detecting errors plus other ant questions

ant

I am trying to write my first build.xml file for an established java project that has just been moved from Netbeans.

A. The objectives that I'm trying to meet are pretty simplistic:

  1. Using the "dest" target below, copy all the source files (4 in all from 1 package) to src/test that I am trying to create. The source files were copied to the "src/test" directory but then a "test" directory was also getting created in the "src/test" directory, why I'm not sure.

  2. Using the "jar" target below, create a jar that has all the class files under the package name directory – DID NOT WORK AT ALL!

  3. Using the "compile" target to ensure that all the code is compiled successfully but I got a lot of errors. The code does CLEAN and BUILD successfully in Eclipse so I'm not sure what I did wrong in the ANT script and one thing I noticed was that it was trying to compile "8" files when there are only "4". Not sure where the other 4 are coming from though it indicates a duplication. The errors show with regard to a missing symbol seem to refer to import statements regarding required projects that are included in the build path so I'm not sure how to address the issues ANT raises in its compile.

B. Here is my first attempt at creating my first build.xml file but I"m experiencing the problems shown below:

<project name="ThalesDataGenerator" basedir="." default="clean-build">

    <property name="src.dir"     value="src"/>
    <property name="dest.dir"    value="${src.dir}/test"/>

    <property name="dist.dir"    value="dist"/>

    <property name="build.dir"   value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir"     value="${build.dir}/${ant.project.name}"/>

    <property name="main-class"  value="thalesdatagenerator.ThalesDataGenerator"/>

    <target name="clean">
        <delete dir="${build.dir}"/>
        <delete dir="${dest.dir}"/>
    </target>

    <target name="compile">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
    </target>

    <target name="dest">
        <mkdir dir="${dest.dir}"/>
        <copy todir="${dest.dir}">  
            <fileset dir="${src.dir}" includes="**"/>  
        </copy>
    </target>

    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/ThalesDataGenerator.jar" basedir="${build.dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>       

    <target name="run" depends="jar">
        <java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
    </target>

    <target name="clean-build" depends="clean,dest,jar,run"/>

</project>

Here are the errors I got:

  • > Buildfile: C:\ATMSwitch\ThalesDataGenerator\build.xml clean:
  • > [delete] Deleting directory C:\ATMSwitch\ThalesDataGenerator\build
  • > dest:
  • > [mkdir] Created dir: C:\ATMSwitch\ThalesDataGenerator\src\test
  • > [copy] Copying 4 files to C:\ATMSwitch\ThalesDataGenerator\src\test
  • > [copy] Copied 2 empty directories to 1 empty directory under C:\ATMSwitch\ThalesDataGenerator\src\test
  • > compile:
  • > [mkdir] Created dir: C:\ATMSwitch\ThalesDataGenerator\build\classes
  • > [javac] C:\ATMSwitch\ThalesDataGenerator\build.xml:22: warning: 'includeantruntime' was not set, defaulting to
    build.sysclasspath=last; set to false for repeatable builds
  • > [javac] Compiling 8 source files to C:\ATMSwitch\ThalesDataGenerator\build\classes
  • > [javac] C:\ATMSwitch\ThalesDataGenerator\src\thalesdatagenerator\ISOUtil.java:36:
    duplicate class: thalesdatagenerator.ISOUtil
  • > [javac] C:\ATMSwitch\ThalesDataGenerator\src\test\thalesdatagenerator\ThalesDataGenerator.java:13:
    package common.database does not exist
  • > [javac] import common.database.Database;
  • > [javac] ^
  • > [javac] C:\ATMSwitch\ThalesDataGenerator\src\test\thalesdatagenerator\ThalesSystem.java:13:
    package com.sharpbancsystems.atmterminals.thales does not exist
  • > [javac] Note: C:\ATMSwitch\ThalesDataGenerator\src\test\thalesdatagenerator\ThalesDataGenerator.java
    uses unchecked or unsafe operations.
  • > [javac] Note: Recompile with -Xlint:unchecked for details.
  • [javac] 18 errors

  • BUILD FAILED

  • C:\ATMSwitch\ThalesDataGenerator\build.xml:22: Compile failed; see the compiler error output for details.

  • Total time: 874 milliseconds

Any help/direction would be greatly appreciated. Regards.

Best Answer

Let's take this one at a time:

A few hints:

  • Use ${basedir} when defining properties. For example, <property name="src.dir" value="${basedir}/src"/> instead of simply value="src"/>
  • Don't force a clean as part of your default target. The standard default target should build the jar and that's it. Doing a clean makes you duplicate work that may not be needed. You can use a target named all to clean, build, and execute.
  • As mentioned above, use the default target names clean to clean up your build, and all to run all targets in your build. Neither of these should be the default target.

Now back to your issue. Your <javac> target looks like this:

<target name="compile">
    <mkdir dir="${classes.dir}"/>
    <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
</target>

Are you saying that there are no third party jars that your source depends upon? You need to create a compile classpath that includes all of the third party jars your source depends upon. In Eclipse, there's a built in classpath you're using. In Ant, you have to specify this.

Let's assume that all jars you need for your source to compile are stored in ${basedir}/lib. Your compile target needs to look like this:

<target name="compile">
    <mkdir dir="${classes.dir}"/>
    <path id="compile.classpath">
        <fileset dir="${basedir}/lib">
           <include name="**/*.jar"/>
        </fileset>
    </path>
    <javac srcdir="${src.dir}" 
        classpathref="compile.classpath"
        destdir="${classes.dir}"/>
</target>

There are many ways of doing this, but this is the easiest syntactically. I use <path> to define a compile.claasspath that contains all of the jars I need. Since they all live in the lib directory, it was pretty easy.

Next, I use the classpathref parameter to specify this classpath when I compile my Java code.

This will get the classes compiled (which isn't happening now). Since compile target fails, the Ant build ends there before the <jar> task is called. Getting the compile to work should allow the rest of your build to work.

Related Topic