Reusable Ant build file
Hello,
I’m back from some vacations.
The topic I want to discuss this time is the use of ant build files. I don’t like the build files generated by netbeans. Why ? Working in a professional environment, you have to master all your building chain : know what happens in the continuous integration process, know exactly what you deliver to your production team (in a professional environment developers package the release and deliver it to production team; only production authorized team deploy the package on production systems), ….
So I don’t like the maze of ant files generated by Netbeans. Here is the reusable ant file I used. you can rapidly use it back in a new project with fex modification (mainly the project name).
This file contains targets for :
-
compilation (at least what a build file must do)
-
generate the javadocĀ (documentation is important, don’t forget it)
-
creating the distribution jar file
-
run target to launch your application, based on the generated jar (this one is an example you’ll have to modify the command line parameters)
-
test your application (with junit), which is important to automate in the case of continuous integration
-
generation of code with jaxb : this can be suppressed (in this case, you can suppress the corresponding mkdir task in prebuild target.
<?xml version="1.0" ?>
<project name="phonebook" basedir="." default="main">
<property name="dist.dir" value="dist"/>
<property name="src.dir" value="src"/>
<property name="src-generated.dir" value="generated-src"/>
<property name="build.dir" value="build"/>
<property name="lib.dir" value="lib"/>
<property name="javadoc.dir" value="${dist.dir}/doc"/>
<property name="version" value="1.1.2"/>
<property name="MainClass" value="fr.free.banks." />
<path id="lib.path">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<pathconvert property="lib.classpath" pathsep=" " dirsep="/">
<path refid="lib.path"></path>
<map from="${basedir}/lib" to="lib"/>
</pathconvert>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
<classpath>
<fileset dir="${lib.dir}" includes="*.jar" />
</classpath>
</taskdef>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
<delete dir="${src-generated.dir}" />
</target>
<target name="prebuild">
<mkdir dir="${build.dir}" />
<mkdir dir="${dist.dir}" />
<mkdir dir="${src-generated.dir}" />
</target>
<target name="main" description="Build complet" depends="clean,create-jar">
<copy todir="${dist.dir}/lib">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</copy>
<copy todir="${dist.dir}">
<fileset dir="${basedir}">
<include name="*.xsd"/>
</fileset>
</copy>
<!--copy todir="${dist.dir}/doc">
<fileset dir="${basedir}/doc">
<include name="**/*.doc"/>
</fileset>
</copy-->
<zip destfile="${ant.project.name}.zip">
<zipfileset dir="dist" />
</zip>
</target>
<target name="compile" description="Compile classes" depends="prebuild,generate-xjc">
<javac srcdir="${src.dir}:${src-generated.dir}" destdir="${build.dir}">
<classpath>
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<target name="generate-xjc" description="Generate classes with JAXB">
<xjc package="fr.free.banks.phonebook.xml" destdir="${src-generated.dir}" >
<classpath>
<pathelement location="${src.dir}"/>
<pathelement path="${jaxbwiz.xjcrun.classpath}"/>
</classpath>
<arg value="-xmlschema"/>
<arg value="-extension"/>
<!--arg value="-Xinject-listener-code" /-->
<schema file="${src.dir}/phonebook.xsd"/>
<produces dir="${src-generated.dir}"/>
</xjc>
</target>
<target name="create-jar" description="Create jar file" depends="compile">
<copy todir="${build.dir}">
<fileset dir="${src.dir}">
<include name="**/log4j.xml"/>
</fileset>
</copy>
<jar jarfile="${dist.dir}/${ant.project.name}.jar" basedir="${build.dir}" includes="**/*.class log4j.xml" >
<manifest>
<section name="${ant.project.name}">
<attribute name="Specification-Version" value="${version}"/>
<attribute name="Implementation-Version" value="${version}"/>
</section>
<attribute name="Main-Class" value="${MainClass}"/>
<attribute name="Class-Path" value="${lib.classpath}"/>
</manifest>
</jar>
</target>
<target name="compile.test" description="Compile test classes">
<mkdir dir="${build.test.dir}" />
<copy todir="${build.dir}">
<fileset dir="${basedir}">
<include name="k.properties" />
</fileset>
</copy>
<javac srcdir="${tst.dir}" destdir="${build.test.dir}" encoding="UTF-8">
<classpath>
<pathelement location="${junit4.dir}/junit.jar" />
<pathelement location="${build.dir}" />
</classpath>
</javac>
</target>
<target name="test" depends="compile.test">
<junit>
<classpath refid="classpath.test" />
<formatter type="brief" />
<!--test name="com.bnpparibas.itp.qm.qos.anonymiser.test.AnonymiserTest" haltonfailure="no" outfile="result">
<formatter type="xml"/>
</test-->
<batchtest fork="yes" todir="buildtest">
<fileset dir="${tst.dir}">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name="javadoc">
<javadoc access="public" author="true" classpath="lib/log4j-1.2.15.jar;C:\Sauvegarde\eclipse-cpp-plugin\eclipse\plugins\org.junit4_4.3.1\junit.jar" destdir="${javadoc.dir}" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" source="1.5" sourcepath="${src.dir}" splitindex="true" use="true" version="true"/>
</target>
<target name="run">
<java classname="fr.free.banks.phonebook.App"
fork="true"
failonerror="true"
maxmemory="128m" >
<classpath>
<pathelement location="${dist.dir}/${ant.project.name}.jar" />
</classpath>
<arg value="-f" />
</java>
</target>
</project>
You can had dependances from other projects in the prebuild target, for example add this :
<copy todir="${lib.dir}">
<fileset dir="${basedir}/../otherproject/dist">
<include name="otherproject.jar"/> </fileset>
</copy>
Hopes this can help you. And don’t hesitate to report possible errors.