This is a pretty extensive example of an ant build.xml file from a real, commercial project. If you run it to get help (which is an option), you'll see this:
Targets: build-compile Build Java code. build-dto-jar Create DTO package JAR for client--required after DTO change! build-war Create WAR file. buildnumber Display build.number value that will be used in package. clean Clean up temporary files and subdirectories. compile-java Compile Java code. debian-build Build Debian package (4). debian-build-number Handle build.number (2). debian-build-with-test Run JUnit tests, build Debian package (4). debian-clean Clean out Debian-package intermediate files (1). debian-prepare Set up to create Debian package (3). erase-database-on-localhost Erase MongoDB database on localhost. jacoco-clean Clean Jacoco intermediate objects (1). jacoco-report Generate Jacoco report (3). jacoco-run Run Jacoco (2). jenkins-build Build WAR for developer sandbox (Jenkins-only target). jenkins-deploy Deploy built WAR to developer sandbox (Jenkins-only target). load-database-on-localhost Reload data into MongoDB database on localhost. load-test-database-on-localhost Reload test data into MongoDB database on localhost. prepare-to-publish Prepare to publish Debian package (5). Best semi-final target to see if build's okay. promote-production Promote package to production (stable) status (6). promote-staging Executes script that promotes package to staging (testing) status (6). publish Publish Debian package (6). refresh-database-on-localhost Refresh MongoDB database on localhost. show-properties See property definitions in force during build. sonar-local Deploy build to local Sonar. sonar-remote Deploy build to remote Sonar. test-clean Clean and build tests (1). test-compile Compile Java test code (2). test-report Report JUnit test results (4). test-run Run JUnit tests (3). Default target: help BUILD SUCCESSFUL Total time: 0 seconds
<?xml version="1.0" ?> <!DOCTYPE project> <project name="accountmgr" default="help"> <property name="dummy" value="Fix Eclipse's ant wagon: take this out and you'll see why it's here!" /> <property name="src.level" value="1.6" /> <property name="target.level" value="1.6" /> <property name="test.compile.verbose" value="true" /> <!-- Here's how to prime the pump: You should keep your own build.properties in extras/private/you/build.properties. Create a link to this file on the local path /opt/acme/apps/accountmgr/conf/build.properties. --> <property file="/opt/acme/apps/accountmgr/conf/build.properties" /> <!-- Everything from here down can be overriden by providing a value in the properties file --> <!-- Add more calculated subdirectory names... --> <property name="app.properties.rootdir" location="/opt/acme/apps/accountmgr" /> <property file="${app.properties.rootdir}/conf/application.properties" /> <property name="build.dir" location="${basedir}/build" /> <property name="dist.dir" location="${basedir}/dist" /> <property name="lib.dir" location="${basedir}/lib" /> <property name="test.lib.dir" location="${lib.dir}/test-only" /> <property name="src.dir" location="${basedir}/src" /> <property name="test.dir" location="${basedir}/test" /> <property name="web.dir" location="${basedir}/WebContent" /> <property name="deploy.dir" location="${build.dir}/deploy" /> <property name="build-classes.dir" location="${build.dir}/classes" /> <property name="test-classes.dir" location="${build.dir}/test-classes" /> <property name="test-reports.dir" location="${build.dir}/test-reports" /> <property name="extras.dir" location="${basedir}/extras" /> <property name="scripts.dir" location="${extras.dir}/debian/scripts" /> <property name="flat_libs.dir" value="deployed-libraries" /> <property name="war.file" value="${dist.dir}/${ant.project.name}.war" /> <property name="debian.dir" location="${build.dir}/debian" /> <property name="debian.control.file" location="${extras.dir}/debian/control" /> <!-- location that the .war file will be placed when the debian package is installed --> <property name="debian.deploy.loc" value="/var/lib/tomcat6/webapps/" /> <property name="app.properties.file" location="${src.dir}/com/acme/web/user/configuration/ApplicationProperties.java" /> <!-- property name="staging.local.dir" location="${extras.dir}/private/staging" / --> <property name="database.shell.script" value="${extras.dir}/reinit_local.sh" /> <property name="erase.database.script" value="${extras.dir}/erase-database.js" /> <property name="load.database.script" value="${extras.dir}/load-database.js" /> <property name="load.test.database.script" value="${extras.dir}/load-test-database.js" /> <property name="deploy.to.sandbox.script" value="${extras.dir}/deploy.sh" /> <property name="dtojar.filename" value="dto.jar" /> <property name="dtojar.version" value="1.0" /> <property name="sonarProjectName" value="Account Management" /> <property name="sonarProjectKey" value="com.acme.web:${ant.project.name}" /> <property name="sonarProjectVersion" value="1.0-SNAPSHOT" /> <property name="jacoco.dir" location="${build.dir}/jacoco" /> <property name="jacoco.report.dir" location="${jacoco.dir}/reports" /> <property name="jacoco.exec.file" value="${jacoco.dir}/jacoco.exec" /> <property file="${basedir}/sonar.properties" /> <property name="sonar.host" value="localhost" /> <property name="sonar.port" value="9000" /> <property name="sonar.context" value="/" /> <property name="sonar.mimosa.host" value="mimosa-crm-sonarserver.usa.acme.com" /> <property name="sonar.mimosa.port" value="9000" /> <property name="sonar.mimosa.context" value="/" /> <!-- P A T H S ========================================================= --> <path id="build-classpath"> <fileset dir="${lib.dir}"> <include name="*/*.jar" /> </fileset> </path> <path id="test-classpath"> <path refid="build-classpath" /> <fileset dir="${test.lib.dir}"> <include name="*/*.jar" /> </fileset> <pathelement path="${build-classes.dir}" /> </path> <path id="junit-classpath"> <path refid="test-classpath" /> <pathelement path="${test-classes.dir}" /> </path> <!-- T A R G E T S ===================================================== --> <target name="help"> <echo message="Numbers on target descriptions indicate relative order in functionality grouping." /> <java classname="org.apache.tools.ant.Main"> <arg value="-projecthelp" /> <arg value="-buildfile" /> <arg value="${ant.file}" /> </java> </target> <target name="show-properties" description="See property definitions in force during build."> <echoproperties /> </target> <!-- c l e a n ========================================================= --> <target name="clean" depends="test-clean" description="Clean up temporary files and subdirectories."> <echo message="Cleaning up old targets..." /> <delete dir="${build.dir}" /> <delete dir="${dist.dir}" /> <delete dir="${flat_libs.dir}" /> <delete file="${extras.dir}/user-management.sql" /> </target> <!-- i n i t =========================================================== --> <target name="init" depends="clean"> <echo message="Initializing..." /> <tstamp /> <mkdir dir="${build-classes.dir}" /> <mkdir dir="${dist.dir}" /> <mkdir dir="${flat_libs.dir}" /> </target> <!-- b u i l d n u m b e r ============================================= --> <target name="buildnumber" description="Display build.number value that will be used in package."> <property file="${basedir}/build.number" /> <echo message="If you publish now, the Debian package build number will be ${build.number}." /> </target> <!-- b u i l d - c o m p i l e ========================================= --> <target name="build-compile" depends="init,compile-java" description="Build Java code."> <echo message="Building Java sources..." /> </target> <!-- c o m p i l e - j a v a =========================================== --> <target name="compile-java" description="Compile Java code."> <echo message="Compiling Java sources..." /> <!-- This needs to be true or Sonar will not work properly --> <property name="compiler.debug" value="true" /> <!-- Java compilation done here... ================================= --> <javac srcdir="${src.dir}" destdir="${build-classes.dir}" source="${src.level}" target="${target.level}" classpathref="build-classpath" debug="${compiler.debug}" debuglevel="lines,vars,source" includeantruntime="false" /> </target> <!-- b u i l d - d t o - j a r ========================================= --> <target name="build-dto-jar" depends="init" description="Create DTO package JAR for client--required after DTO change!"> <echo message="Compiling Java sources..." /> <!-- Java compilation done here... ================================= --> <javac srcdir="${src.dir}" destdir="${build-classes.dir}" source="${src.level}" target="${target.level}" classpathref="build-classpath" includes="com/acme/web/user/dto/**" debug="true" debuglevel="lines,vars,source" includeantruntime="false" /> <javac srcdir="${src.dir}" destdir="${build-classes.dir}" source="${src.level}" target="${target.level}" classpathref="build-classpath" includes="com/acme/web/staticdata/**" debug="true" debuglevel="lines,vars,source" includeantruntime="false" /> <!-- The DTO classes are used for incoming REST requests to consolidate JSON into objects. External clients wanting to generate those requests programmatically should use the same classes so that they don't get out of sync. October, 2013: added the static data classes too. So these packages: com.acme.web.user.dto com.acme.web.staticdata Important note!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! If a DTO is modified in accountmgr, e.g.: a new field and/or method is added or one is taken away, you must use this target to build the DTO JAR, copy it to client, build client, then copy the client JAR back to here. If you do not do this, a) the Jenkins build, which runs tests using client (CLASSPATH ordering problem), will fail due to failed test b) ant test-run will fail locally, but... c) JUnit tests will not fail from Eclipse (i.e.: you won't notice anything's wrong.) --> <echo message="Jaring DTO package..." /> <jar jarfile="${dist.dir}/${dtojar.filename}"> <fileset dir="${build-classes.dir}"> <include name="com/acme/web/user/dto/*.class" /> <include name="com/acme/web/staticdata/*.class" /> </fileset> <fileset dir="${src.dir}"> <include name="com/acme/web/user/dto/*.java" /> <include name="com/acme/web/staticdata/*.java" /> </fileset> <manifest> <attribute name="Built-By" value="${user.name}" /> <attribute name="Specification-Title" value="DTO and static data classes" /> <attribute name="Specification-Version" value="${dtojar.version}" /> <attribute name="Specification-Vendor" value="Hewlett-Packard Development Company, L.P." /> <attribute name="Implementation-Title" value="dto" /> <attribute name="Implementation-Version" value="${dtojar.version}" /> <attribute name="Implementation-Vendor" value="Hewlett-Packard Development Company, L.P." /> </manifest> </jar> </target> <!-- b u i l d - w a r ================================================= --> <target name="build-war" depends="build-compile" description="Create WAR file."> <!-- Get build.number, if not already set --> <property file="${basedir}/build.number" /> <echo message="Creating WAR file: BUILD ${build.number}" /> <copy file="${src.dir}/log4j.properties" todir="${build-classes.dir}" /> <copy todir="${flat_libs.dir}" flatten="true"> <fileset dir="${lib.dir}"> <include name="**/*.jar" /> <exclude name="**/misc-doc/**" /> <exclude name="**/non-deploy/**" /> <exclude name="**/test-only/**" /> <exclude name="**/*-sources.jar" /> <exclude name="**/*-javadoc.jar" /> </fileset> </copy> <war destfile="${war.file}" webxml="${web.dir}/WEB-INF/web.xml"> <fileset dir="${web.dir}" /> <lib dir="${flat_libs.dir}" /> <classes dir="${build-classes.dir}" /> <manifest> <attribute name="Built-By" value="Web Platform Team" /> <attribute name="Implementation-Title" value="User Account Service" /> <attribute name="Implementation-Version" value="1.00.${build.number}" /> <attribute name="Implementation-Vendor" value="Hewlett-Packard Development Company, LP." /> </manifest> </war> <copy file="${war.file}" todir="${deploy.dir}" /> </target> <!-- == D E B I A N P A C K A G E A N D B U I L D ======================================= --> <!-- Sources for what goes into a package comes out of extras. extras +- debian | `- control +- scripts +- private | `- staging | +- certs | +- conf | +- keys | | `- oauth | +- keystore +- accountmgr_db.js +- crontab.sh +- reinit_db.js `- update-installation.sh These all go to creating something like this: build `- debian +- accountmgr | `- DEBIAN | `- control +- opt | `- acme | `- apps | `- accountmgr | +- certs | | `- mimosa.qa.acme.com_ssl.cer | +- keys | | +- oauth | | | +- sf_v1a-int_public.key | | | +- sf_v1a-stg_public.key | | | `- v1.a_public.key | | `- secret.key | +- keystore | | `- client.keystore | `- scripts | +- accountmgr_db.js | +- crontab.sh | +- reinit_db.js | `- update-installation.sh `- var `- lib `- tomcat6 `- webapps `- accountmgr.war --> <!-- == D E B I A N P A C K A G E A N D B U I L D ======================================= --> <!-- d e b i a n - c l e a n =========================================== --> <target name="debian-clean" description="Clean out Debian-package intermediate files (1)."> <echo message="Cleaning up Debian work area (${debian.dir})..." /> <delete dir="${debian.dir}" /> </target> <!-- d e b i a n - b u i l d - n u m b e r --> <target name="debian-build-number" description="Handle build.number (2)."> <!-- Retreive value into build.number and THEN increment for next time --> <buildnumber /> <echo message="Using build.number --> ${build.number}" /> <!-- Inject build number into Debian control file ================== --> <echo message=" Build number is: ${build.number}" /> <echo message=" Injecting new build number into Debian control file..." /> <replaceregexp file="${debian.control.file}" byline="true"> <regexp pattern="Version: 1.00.[0-9]*" /> <substitution expression="Version: 1.00.${build.number}" /> </replaceregexp> <echo message="Update build timestamp into ApplicationProperties.java..." /> <tstamp><format property="BUILD_TIME" pattern="yyMMddHHmmssZ" /></tstamp> <!-- Tweaking of ApplicationProperties.java code... ================ --> <!-- This must be done before compiling code (build-war) or it won't be included --> <echo message="Inject new build number and build timestamp into ApplicationProperties.java..." /> <echo message=" build number: ${build.number}, build timestamp: ${BUILD_TIME}" /> <replaceregexp file="${app.properties.file}" byline="true"> <regexp pattern="REVISION = "[0-9]*";" /> <substitution expression="REVISION = "${build.number}";" /> </replaceregexp> <replaceregexp file="${app.properties.file}" byline="true"> <regexp pattern="BUILD_TIME = "[0-9]*[<-<+][0-9]*";" /> <substitution expression="BUILD_TIME = "${BUILD_TIME}";" /> </replaceregexp> </target> <!-- d e b i a n - p r e p a r e ======================================= --> <target name="debian-prepare" depends="debian-clean,debian-build-number,build-war" description="Set up to create Debian package (3)."> <!-- Create debian directory structure --> <echo message="Creating Debian package build directories..." /> <mkdir dir="${debian.dir}/${ant.project.name}/DEBIAN/" /> <mkdir dir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/keys/oauth/" /> <mkdir dir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/keystore/" /> <!--mkdir dir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/scripts/" /--> <echo message=" Copying control (version) file..." /> <copy todir="${debian.dir}/${ant.project.name}/DEBIAN/"> <fileset dir="${extras.dir}/debian/"> <include name="**/control" /> </fileset> </copy> <!-- Don't know why we need certs since they are on loadbalancers --> <!--echo message=" Copying SSL certificates to package area..." /> <copy todir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/certs/" failonerror="false"> <fileset dir="${staging.local.dir}/certs/"> <include name="**/*.cer" /> </fileset> </copy --> <echo message=" Copying key files to package area..." /> <copy todir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/keys" failonerror="false"> <fileset dir="${extras.dir}/private/keys"> <include name="**/*.key" /> </fileset> </copy> <copy todir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/keys/oauth" failonerror="false"> <fileset dir="${extras.dir}/private/keys/oauth"> <include name="**/*.key" /> </fileset> </copy> <echo message=" Copying keystore files to package area..." /> <copy todir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/keystore/" failonerror="false"> <fileset dir="${extras.dir}/private/keystore/"> <include name="**/*.keystore" /> </fileset> </copy> <!-- None of these scripts actually exist <echo message=" Copying script files to package area..." /> <copy todir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/scripts/" failonerror="false"> <fileset dir="${extras.dir}/"> <include name="reinit_db.sh" /> <include name="crontab.sh" /> <include name="update-installation.sh" /> <include name="accountmgr_db.js" /> </fileset> </copy> <echo message=" Fix up permissions on script files in package area..." /> <chmod perm="a+x"> <fileset dir="${debian.dir}/${ant.project.name}/opt/acme/apps/${ant.project.name}/scripts/"> <include name="*.sh" /> </fileset> </chmod> --> <echo message=" Copying WAR file..." /> <copy file="${war.file}" todir="${debian.dir}/${ant.project.name}${debian.deploy.loc}" /> </target> <!-- d e b i a n - b u i l d =========================================== --> <target name="debian-build-with-test" depends="test-run,debian-prepare" description="Run JUnit tests, build Debian package (4)." /> <target name="debian-build" depends="debian-prepare" description="Build Debian package (4)."> <echo message="Building the Debian package with build number ${build.number}..." /> <echo message=" Copying packaging scripts..." /> <copy todir="${debian.dir}"> <fileset dir="${scripts.dir}"> <include name="**/*.sh" /> </fileset> </copy> <chmod dir="${debian.dir}" perm="+x" includes="**/*.sh" /> <exec dir="${debian.dir}" executable="./build-package.sh" /> <copy todir="${dist.dir}" file="${debian.dir}/${ant.project.name}.deb" /> </target> <!-- p r e p a r e - t o - p u b l i s h =============================== --> <target name="prepare-to-publish" depends="debian-build" description="Prepare to publish Debian package (5). Best semi-final target to see if build's okay."> <!-- This is complicated: ant can't execute shell commands, but only scripts. We 1) Make the package (accountmgr.deb). 2) List its details so you can be sure of what you're submitting. This target does everything except actually publishing; it's the target to use to run a "dry-publish". --> <echo message="Preparing to publish the Debian package with build number ${build.number}..." /> <exec dir="${debian.dir}" executable="./build-package.sh" /> <exec dir="${debian.dir}" executable="./get-package-info.sh" /> </target> <!-- p u b l i s h ===================================================== --> <target name="publish" depends="prepare-to-publish" description="Publish Debian package (6)."> <!-- Use publish-package.sh to publish to the Acme/Aptitude repository, development status (unpromoted). To publish to staging or production, you must first publish to development (unstable), then use one of the other targets below, which do not build or publish anything, to promote an existing package. --> <property name="APT_CMD" value="acme-apt -d publish ${debian.dir}/${ant.project.name}.deb${line.separator}" /> <echo file="${debian.dir}/scripts/publish-package.sh" message="#!/bin/sh${line.separator}${line.separator}" /> <echo file="${debian.dir}/scripts/publish-package.sh" message="echo ${APT_CMD}" append="true" /> <echo file="${debian.dir}/scripts/publish-package.sh" message="${APT_CMD}" append="true" /> <chmod file="${debian.dir}/scripts/publish-package.sh" perm="+x" type="both" /> <exec dir="${debian.dir}/scripts/" executable="./publish-package.sh" /> </target> <!-- p r o m o t e - s t a g i n g ===================================== --> <target name="promote-staging" description="Executes script that promotes package to staging (testing) status (6)."> <!-- Endow publish-package.sh with a statement to promote to staging. This target will not make use of anything built in this invocation, but only promote what's already in the Acme/Aptitude unstable repository to the testing or QA repository. --> <echo message="Promote package to staging (QA/testing) repository..." /> <echo file="${debian.dir}/scripts/publish-package.sh" message="#!/bin/sh${line.separator}" /> <echo file="${debian.dir}/scripts/publish-package.sh" message="acme-apt -d promote ${debian.dir}/accountmgr.deb --dist testing${line.separator}" append="true" /> <chmod file="${debian.dir}/scripts/publish-package.sh" perm="+x" type="both" /> <exec dir="${debian.dir}/scripts/" executable="./publish-package.sh" /> </target> <!-- p r o m o t e - p r o d u c t i o n =============================== --> <target name="promote-production" description="Promote package to production (stable) status (6)."> <!-- Endow publish-package.sh with a statement to promote to production. This target will not make use of anything built in this invocation, but only promote what's already in the Acme/Aptitude unstable or testing repository to the production repository. --> <echo message="Publish Debian package to product (stable) repository..." /> <echo file="${debian.dir}/scripts/publish-package.sh" message="#!/bin/sh${line.separator}" /> <echo file="${debian.dir}/scripts/publish-package.sh" message="acme-apt -d promote ${debian.dir}/accountmgr.deb --dist stable${line.separator}" append="true" /> <chmod file="${debian.dir}/scripts/publish-package.sh" perm="+x" type="both" /> <exec dir="${debian.dir}/scripts/" executable="./publish-package.sh" /> </target> <!-- == j e n k i n s - b u i l d - a n d - d e p l o y ====================================== --> <target name="jenkins-build" depends="test-run,build-war" description="Build WAR for developer sandbox (Jenkins-only target)."> <echo message="Jenkins building for deployment to developer sandbox..." /> </target> <target name="jenkins-deploy" depends="jenkins-build" description="Deploy built WAR to developer sandbox (Jenkins-only target)."> <echo message="Jenkins deploying built WAR to developer sandbox..." /> <chmod perm="a+x" file="${deploy.to.sandbox.script}" /> <exec executable="${deploy.to.sandbox.script}" /> </target> <!-- r e f r e s h - d a t a b a s e - o n - l o c a l h o s t ========= --> <target name="refresh-database-on-localhost" depends="erase-database-on-localhost,load-database-on-localhost,load-test-database-on-localhost" description="Refresh MongoDB database on localhost."> <!-- This refreshes (bounces) the local MongoDB or the replica set on Black Pearl --> <echo message="Refreshing database with ${database.shell.script}..." /> <echo message=" This consists of removing all the databases and collections to start over..." /> <echo message=" ...from scratch and adding some cool stuff." /> </target> <!-- e r a s e - d a t a b a s e - o n - l o c a l h o s t ========= --> <target name="erase-database-on-localhost" description="Erase MongoDB database on localhost."> <echo message="Erasing {database.shell.script}..." /> <exec executable="/bin/bash"> <arg value="${database.shell.script}" /> <arg value="${erase.database.script}" /> </exec> </target> <!-- l o a d - d a t a b a s e - o n - l o c a l h o s t ========= --> <target name="load-database-on-localhost" description="Reload data into MongoDB database on localhost."> <echo message="Reloading database with ${database.shell.script}..." /> <exec executable="/bin/bash"> <arg value="${database.shell.script}" /> <arg value="${load.database.script}" /> </exec> </target> <!-- l o a d - t e s t - d a t a b a s e - o n - l o c a l h o s t ========= --> <target name="load-test-database-on-localhost" description="Reload test data into MongoDB database on localhost."> <echo message="Reloading test data into database with ${database.shell.script}..." /> <exec executable="/bin/bash"> <arg value="${database.shell.script}" /> <arg value="${load.test.database.script}" /> </exec> </target> <!-- r e f r e s h - d b - w i n d o w s ========= --> <target name="refresh-db-windows"> <echo message="Refreshing database with mongo, if found on path" /> <echo message="Dropping dbs ..." /> <exec executable="cmd"> <arg value="/c"/> <arg value="mongo" /> <arg value="localhost:27017/accountmgrdb" /> <arg value="${erase.database.script}" /> </exec> <echo /> <echo message="Loading essential data..." /> <exec executable="cmd"> <arg value="/c"/> <arg value="mongo" /> <arg value="localhost:27017/accountmgrdb" /> <arg value="${load.database.script}" /> </exec> <echo /> <echo message="Loading test data..." /> <exec executable="cmd"> <arg value="/c"/> <arg value="mongo" /> <arg value="localhost:27017/accountmgrdb" /> <arg value="${load.test.database.script}" /> </exec> </target> <!-- d o c ============================================================= --> <target name="doc" depends="init"> <echo message="Generating Javadoc..." /> <javadoc packagenames="*" sourcepath="${src.dir}" classpathref="build-classpath" destdir="${build.dir}/classes" /> </target> <!-- == Building and running tests =========================================================== --> <!-- t e s t - c l e a n =============================================== --> <target name="test-clean" description="Clean and build tests (1)."> <echo message="Cleaning up test classes ..." /> <delete dir="${test-classes.dir}" /> </target> <!-- t e s t - c o m p i l e =========================================== --> <target name="test-compile" depends="build-compile" description="Compile Java test code (2)."> <echo message="Compiling tests..." /> <mkdir dir="${test-classes.dir}" /> <javac srcdir="${test.dir}" destdir="${test-classes.dir}" source="${src.level}" target="${target.level}" classpathref="test-classpath" debug="true" debuglevel="lines,vars,source" includeAntRuntime="no" verbose="${test.compile.verbose}" /> </target> <!-- t e s t - r u n =================================================== --> <target name="test-run" depends="test-compile" description="Run JUnit tests (3)."> <echo message="Running tests..." /> <mkdir dir="${test-reports.dir}" /> <junit printsummary="yes" haltonfailure="no" failureproperty="isUnitTestFailed" fork="yes" forkmode="once"> <classpath refid="junit-classpath" /> <formatter type="xml" /> <batchtest fork="yes" todir="${test-reports.dir}"> <fileset dir="${test.dir}" includes="**/*Test.java" /> </batchtest> </junit> </target> <!-- t e s t - r e p o r t ============================================= --> <target name="test-report" depends="test-run" description="Report JUnit test results (4)."> <echo message="Reporting tests..." /> <junitreport todir="${build.dir}"> <fileset dir="${test-reports.dir}"> <include name="TEST-*.xml" /> </fileset> <report format="frames" todir="${build.dir}" /> </junitreport> </target> <!-- == Code coverage with Sonar (dependent on Jacoco) ===================================== --> <!-- s o n a r - r e m o t e ============================= --> <!-- == Code coverage with Sonar (dependent on Jacoco) ===================================== --> <target name="sonar-remote" depends="jacoco-clean,jacoco-report" description="Deploy build to remote Sonar."> <echo message="Deploying to remote Sonar..." /> <property name="sonar.host.url" value="http://${sonar.mimosa.host}:${sonar.mimosa.port}${sonar.mimosa.context}" /> <property name="sonar.jdbc.url" value="jdbc:mysql://${sonar.mimosa.host}:3306/sonar?useUnicode=true&characterEncoding=utf8" /> <property name="sonar.jdbc.driverClassName" value="com.mysql.jdbc.Driver" /> <property name="sonar.jdbc.username" value="sonar" /> <property name="sonar.jdbc.password" value="sonar" /> <property name="sonar.projectName" value="${sonarProjectName}" /> <property name="sonar.projectKey" value="${sonarProjectKey}" /> <property name="sonar.projectVersion" value="${sonarProjectVersion}" /> <property name="sonar.language" value="java" /> <property name="sonar.sources" value="${src.dir}" /> <property name="sonar.binaries" value="${build-classes.dir}" /> <property name="sonar.libraries" value="${lib.dir}/common/*.jar" /> <property name="sonar.tests" value="${test.dir}" /> <property name="sonar.dynamicAnalysis" value="reuseReports" /> <property name="sonar.surefire.reportsPath" value="${test-reports.dir}" /> <!-- Tells Sonar which code coverage tool to use --> <property name="sonar.java.coveragePlugin" value="jacoco" /> <!-- Tells Sonar where the unit tests code coverage report is --> <property name="sonar.jacoco.reportPath" value="${jacoco.exec.file}" /> <!-- Tells Sonar where the integration tests code coverage report is --> <!--property name="sonar.jacoco.itReportPath" value="${jacoco.exec.file}" /--> <sonar:sonar xmlns:sonar="antlib:org.sonar.ant" /> </target> <!-- s o n a r - l o c a l =================== --> <target name="sonar-local" depends="jacoco-clean,jacoco-report" description="Deploy build to local Sonar."> <echo message="Deploying to local Sonar..." /> <property name="sonar.host.url" value="http://${sonar.host}:${sonar.port}${sonar.context}" /> <property name="sonar.projectName" value="${sonarProjectName}" /> <property name="sonar.projectKey" value="${sonarProjectKey}" /> <property name="sonar.projectVersion" value="${sonarProjectVersion}" /> <property name="sonar.language" value="java" /> <property name="sonar.sources" value="${src.dir}" /> <property name="sonar.binaries" value="${build-classes.dir}" /> <property name="sonar.libraries" value="${lib.dir}/common/*.jar" /> <property name="sonar.tests" value="${test.dir}" /> <property name="sonar.dynamicAnalysis" value="reuseReports" /> <property name="sonar.surefire.reportsPath" value="${test-reports.dir}" /> <!-- use 'forceAnalysis' is a sonar anaylsis was stopped prematurely and now think one is already running --> <!-- property name="sonar.forceAnalysis" value="true" / --> <!-- Tells Sonar which code coverage tool to use --> <property name="sonar.java.coveragePlugin" value="jacoco" /> <!-- Tells Sonar where the unit tests code coverage report is --> <property name="sonar.jacoco.reportPath" value="${jacoco.exec.file}" /> <!-- Tells Sonar where the integration tests code coverage report is --> <!--property name="sonar.jacoco.itReportPath" value="${jacoco.exec.file}" /--> <sonar:sonar xmlns:sonar="antlib:org.sonar.ant" /> </target> <!-- == Code coverage with Jacoco ========================================================== --> <!-- Jacoco requires the jacocoant.jar to be added to the ANT_HOME/lib. This file can be downloaded from http://jacoco.org/jacoco/index.html. --> <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml" /> <!-- j a c o c o - c l e a n =========================================== --> <target name="jacoco-clean" description="Clean Jacoco intermediate objects (1)."> <echo message="Cleaning up Jacoco..." /> <delete dir="${jacoco.dir}" /> </target> <!-- j a c o c o - r e p o r t ========================================= --> <target name="jacoco-report" depends="jacoco-run" description="Generate Jacoco report (3)."> <echo message="Generating Jacoco reports..." /> <jacoco:report xmlns:jacoco="antlib:org.jacoco.ant"> <executiondata> <file file="${jacoco.exec.file}"/> </executiondata> <structure name="JaCoCo Reports"> <classfiles> <fileset dir="${build-classes.dir}"/> </classfiles> <sourcefiles encoding="UTF-8"> <fileset dir="${src.dir}"/> </sourcefiles> </structure> <html destdir="${jacoco.report.dir}"/> <xml destfile="${jacoco.report.dir}/report.xml"/> </jacoco:report> </target> <!-- j a c o c o - r u n =============================================== --> <target name="jacoco-run" depends="test-compile" description="Run Jacoco (2)."> <mkdir dir="${test-reports.dir}" /> <jacoco:coverage xmlns:jacoco="antlib:org.jacoco.ant" destfile="${jacoco.exec.file}"> <junit printsummary="yes" haltonfailure="no" failureproperty="isUnitTestFailed" fork="yes" forkmode="once"> <classpath refid="junit-classpath" /> <formatter type="xml" /> <batchtest fork="yes" todir="${test-reports.dir}"> <fileset dir="${test.dir}" includes="**/*Test.java" /> </batchtest> </junit> </jacoco:coverage> </target> </project>
Contents of build.number (after the 153rd build invocation):
#Build Number for ANT. Do not edit! #Wed Sep 11 11:43:24 MDT 2013 build.number=153
Unlike using Maven's pom.xml in an IDE (like IntelliJ IDEA or Eclipse), build.xml isn't adequately exploited for dependencies. In the libs subdirectory implied above, are JARs that neither IDE will bring in for its build. I'm not sure why this is, but it's a reality.
The solution for IDEA is the Project Structure → Modules → Dependencies tab. In Eclipse (this goes back the better part of a decade for me), there's Build Path and a way to add library JARs. The last time I used Eclipse, Build Path had disappeared and I didn't take the time to investigate. This simply means that there are two builds: one for command line/Jenkins/whatever and one for the IDE. A bit of nasty asymmetry.