Making your builds boring…
• Building projects should be easy and standardized. You should not be spending a substantial amount of your project time on
builds. Builds should just work!
Introduction to Ant• Ant is a “build tool” – especially useful to
compile, package, deploy Java projects• It can do much more - file operations, version
control/CVS, XML validations/transforms, run system commands, custom tasks, etc
• Ant is suitable also for all kinds of Java-unrelated file manipulations, e.g. preprocessing static stuff in Web publishing
• Ant’s alternatives are “batch” files under Windows, Makefile-s or shellscripts under UNIX. Build scripts may be written in other scripting languages as well
Ant in Java Projects• Even when there is IDE build environment, it is
useful to have Ant script to build and deploy (everything is transparent there)
• In big projects build scripts are usually written by “Technical Designer” or qualified developer
• Other developers ideally just need to remember a few commands, e.g.
ant -projecthelp (lists targets and their descriptions)ant junit (rebuild and run JUnit tests)ant deploy (build and deploy for a system test)
Ant and IDE tools• They are complementary: Ant build scripts can
automate all kinds of build processes• Use IDE (e.g. Eclipse) for editing, unit-testing
and version-controlling code; use Ant for doing more complex development tasks, e.g. deployments and system tests
• Eclipse plugins can solve similar issues as Ant can, but Ant is free and easier to standardize
Ant Features• Build-scripts are written using a special XML
syntax
• “Ant tasks” represent object-oriented approach to build process. Tasks can inherit from each other.
• Build-file language does not have flow control features:
• loops/iterators, if-constructs, try-catch constructs
• Instead it is based on recursive nature of Ant’s tasks and Ant’s datatypes filesets, patterns, filters, mappers, etc
Build File• XML format• Typically in project root directory• Default name: build.xml• Declarative - define steps, not scripty details• Defines a single project• A project contains targets• Targets contain tasks
Projects• A project has three attributes:
• name - the name of the project• default - the default target to use when no target is supplied• basedir - the base directory from which all path calculations
are done
• Each project defines one or more targets
<?xml version="1.0" ?><project name="sample" default="deploy" basedir=".">
<target name="clean" description="Removes build artifacts"> …</target>
</project>
Targets• A target can depend on other targets
• A target has the following attributes:• name - the name of the target• depends - a comma-separated list of names of targets on which
this target depends• if - the name of the property that must be set in order for this
target to execute• unless - the name of the property that must not be set in order
for this target to execute• description - a short description of this target's function
<target name="A"/> <target name="B" depends="A"/> <target name="C" depends="B"/>
<target name="D“ depends="C,B,A"/> DCBA
>ant D
Dependency resolution
Tasks• A task is a piece of code that can be executed• Tasks have a common structure:
• <name attribute1="value1" attribute2="value2" ... />
• There is a set of built-in tasks:• <mkdir>, <copy>, <delete>• <javac>, <java>• <jar>, <zip>• many more…
• It is very easy to write your own task:• Extend a org.apache.tools.ant.Task class• Implement specific stuff like attributes, nested tasks etc.• Write a public void execute method, with no
arguments, that throws a BuildException. This method implements the task itself.
Properties• A project can have a set of properties• ${property.name} to access property value• Properties can be defined:
• In Ant file itself (name/value) <property name="site" value="sample"/>
• In one or more external properties file <property file="sites/${site}/config.properties”
prefix="site"/>
• In the command line > ant -Dappname=newstuff jar
• Environment variables can be accessed<property environment="env"/><echo message="Number of Processors=${env.NUMBER_OF_PROCESSORS}"/>
Ant Data Types• Commonly used built-in data types:
• Path• Ordered list of path elements, analogous to Java CLASSPATH, contains files and/or directories
• Fileset
• Unordered set of files from a single root directory
• Patternset
• Selectors, Filterset, and others…
<path id="anttask.compile.classpath"> <pathelement location="${lucene.jar}"/> <pathelement location="${jtidy.jar}"/></path>
<fileset dir="web" excludes="search.jsp"/><fileset dir="${build.dir}/${site}" includes="*.jsp"/>
<patternset id=“java.files.pattern” includes=“**/*.java”/> <fileset dir="src"> <patternset refid=“java.files.pattern”/></fileset>
Example build file<project name="MyProject" default="dist" basedir="."><description>Simple example build file</description>
<!-- set global properties for this build --> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/>
<target name="init"> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target>
<target name="compile" depends="init" description="compile the source " > <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target>
<target name="dist" depends="compile" description="generate the distribution" > <mkdir dir="${dist}/lib"/> <!-- Put everything in ${build} into the MyProject.jar file --> <jar jarfile="${dist}/lib/MyProject.jar" basedir="${build}"/> </target>
<target name="clean“ description="clean up" > <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target></project>
Installing Ant• Download from http://ant.apache.org
• current version 1.7.0 / 2006-12-19• Precondition – install J2SE (or JRE) and set
variable %JAVA_HOME%• Unpack Ant’s installation and set variable
%ANT_HOME%• Add %ANT_HOME%\bin to your %PATH% variable
to enable running “ant.bat” utility from any DOS window
Running Ant Targets• Ant targets can be executed from command line:
• Execute default target:> ant
• Execute specific target:> ant deploy-jboss
• Execute multiple targets:> ant test-common generate-test-reports
> ant deploy-jboss -Dsite=personalBuildfile: build.xml
init: [echo] Building for personal site.
. . .
deploy-jboss: [copy] Copying 1 file to /Users/erik/jboss-3.0.0/server/default/deploy
BUILD SUCCESSFULTotal time: 18 seconds
Debugging Ant• By default, Ant’s messages for failed tasks might
be insufficient. You can easily make Ant more verbose to see what it is doing:
ant -verbose taskname
ant -debug taskname (very verbose)
• These will show each elementary action performed by the build process
File TasksTask Name Descriptionmkdir Creates a directory. Non-existent parent directories are created, when
necessary.
delete Deletes either a single file, all files and sub-directories in a specified directory, or a set of files specified by one or more FileSets.
copy Copies a file or Fileset to a new file or directory.
move Moves a file to a new file or directory, or a set(s) of file(s) to a new directory.
chmod Changes the permissions of a file or all files inside the specified directories. Currently, it has effect only under Unix. The permissions are also UNIX style, like the arguments for the chmod command.
get Gets a file from a URL.
More tasks: concat, replace, chown, sync, tempfile, touch,…
More Tasks…• <javac>
Compiles a Java
source tree
• <jar>
Jars a set of files
• <war>
Creates Web
Application Archive
<javac srcdir="src" destdir="${build.dir}/WEB-INF/classes" debug="${javac.debug}" classpathref="compile.classpath"/>
<jar basedir="${build.dir}"
jarfile="${name}.jar“
includes="**/*.class"/>
<war destfile="myapp.war"
webxml="${web.dir}/WEB-INF/web.xml">
<fileset dir="WebRoot"/> <lib dir="${lib.dir}"> <exclude name="jdbc1.jar"/> </lib> <classes dir="${build.dir}/bin"/>
</war>
More Tasks…• <java>
Executes Java
class
• <echo>
Prints a message
• <junit>
Runs
JUnit
tests
<java classname="test.Main"> <arg value="-h"/> <classpath> <pathelement location="dist/test.jar"/> <pathelement path="${java.class.path}"/> </classpath></java>
<echo message="Hello, world"/>
<echo message=“Line break:${line.separator}"/>
<echo level="error">Fatal error!</echo>
<junit> <test name="my.test.TestCase"/></junit>
<junit printsummary="yes" fork="yes" haltonfailure="yes"> <formatter type="plain"/> <test name="my.test.TestCase"/></junit>
References• Ant Home
http://jakarta.apache.org/ant
• Ant Online Manual http://ant.apache.org/manual/index.html
• Books on Ant • Ant Developer's Handbook by Alan Williamson, Kirk Pepperdine, Joey
Gibson, Andrew Wu• Java™ Extreme Programming Cookbook by Eric M. Burke, Brian M.
Coyner• Java Development With Ant by Erik Hatcher, Steve Loughran
http://www.amazon.com/exec/obidos/ASIN/1930110588
Top Related