390 likes | 581 Views
Apache Ant. Java-Based Build Tool. 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.
E N D
Apache Ant Java-Based Build Tool
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
Typical Things to Build • Classes • JARs • WARs • EARs • JavaDocs • Documentation HTML/PDF
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>
A B C D 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 >ant D Dependency resolution <target name="A"/> <target name="B" depends="A"/> <target name="C" depends="B"/><target name="D“depends="C,B,A"/>
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.Taskclass • 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=personal Buildfile: 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 SUCCESSFUL Total 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 tasknameant -debug taskname(very verbose) • These will show each elementary action performed by the build process
File Tasks 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 classname="test.Main"> <arg value="-h"/> <classpath> <pathelement location="dist/test.jar"/> <pathelement path="${java.class.path}"/> </classpath> </java> • <java> Executes Java class • <echo> Prints a message • <junit> Runs JUnit tests <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