Saturday, October 9, 2010

How to write build.xml and run build in Apache ANT

This is the second article on Apache ANT tutorials for beginners series As I have always said that I like short , clear and concise tutorial which tells about few concept but in a clear and concise manner and put weight on fundamentals . I try to adopt same theory while writing my blog post while writing my experience coupled with concept which is important for a software developer point of view.

How to write build.xml and run build in Apache ANT
Here I am answering some of the basic questions related to installing ant , running ant , creating buidl.xml file , debugging build.xml in case of any issue .

These questions have been asked by my students , while teaching them JAVA and related technology  in my early career.

How do I run ant?
To run you need to download ant and install on your machine , then create environment variable ANT_HOME and include ANT_HOME/bin into your PATH like below.

In Windows path=%path%;%ANT_HOME%/bin
In Linux    PATH =${PATH}:${ANT_Home}/bin


Now you can open command prompt and type ant.

If you get this output, means ant binaries is not in your path

C:\Documents and Settings>ant
'ant' is not recognized as an internal or external command,operable program or batch file.

Otherwise you will get output which will complain about build file if it doesn’t exits.
   
    C:\Documents and Settings>ant
    Buildfile: build.xml does not exist!
    Build failed


How do I write build.xml file?
here is a sample build.xml you just need to know important element e.g. project ,target ,property and task and the order in which different target gets executed to start with basic build procedure.

<?xml version="1.0"?>
<project name="test" default="all" basedir=".">
  <property name="src"   value="src"/>
  <property name="build" value="build"/>
  <property name="lib"   value="lib"/>

<target name="all" depends="clean, compile" description="Builds the whole project">
    <echo>Doing all</echo>
  </target>

<target name="Clean" description="Removes previous build">
    <delete verbose="true">
      <fileset dir="${build}"/>
    </delete>
  </target>

<target name="compile" depends="clean" description="compile whole project">
    <echo>compile ${ant.project.name} </echo>
    <copy file="${src}/splashscreen.jpeg" tofile="${build}/splashscreen.jpeg"/>
    <javac srcdir="${src}" destdir="${build}" includes="Test.java"/>
  </target>
</project>


lets see what we are doing here :

<project name="test" default="all" basedir=".">


This line defines our project; every build file must have this line. Project name is “test” defined by attribute “name”; default target is “all”, while running “ant” command from commmand prompt if we don’t specify any target than ant executed this default target.
basedir tells which is top level directory for creating build in this case its current directory (from where you run ant command) , denoted by dot “.” .

<property name="src"   value="src"/>

Here we are declaring and specifying property ,you can say variable every property has atleast two attribute “name” and “value” , though you can define your all properties in a separate properties file and load from there as well .<property> denotes ant’s property task, which do have some other attribute e.g. location to specify location of any properties file. I recommend that you always use property in your build.xml instead of using hardcoded values in target for directory name etc , this will give you flexibility to change the value anytime without changing at many places (in case you have hardcoded it).

<target name="all" depends="clean, compile" description="Builds the whole project">

Here we are defining a target, since we have already called target “all” as default in project tag, so if we don’t specify this target our build will fail saying “target not found”.

”name” attribute specified name of target. “depends” says that before executing this target executed first “clean” and then “compile”

<echo>Doing all</echo>

This will print message in console as “doing all”


<target name="Clean" description="Removes previous build">

This is target “Clean” which will delete old build before building new one , you can have as many target as you want based on your need.

<delete verbose="true">
      <fileset dir="${build}"/>
</delete>


delete task or tag is used to delete directory, file etc, verbose=true makes it to print message while deleting in cosole, <fileset> is an important tag and I recommend you to read in detail somewhere in ant manual or may be I will explain in detail sometime because it include “patternset” which supports pattern matching of directory/files via its includes and excludes attribute which is extremely useful to filter unwanted files (generally meta data files form CVS, SVN etc).

Here we are deleting build directory by using value of property “build”, ${build} denotes value of any property.

<target name="compile" depends="clean" description="compile whole project">
    <echo>compile ${ant.project.name} </echo>
    <copy file="${src}/splashscreen.jpeg" tofile="${build}/splashscreen.jpeg"/>
    <javac srcdir="${src}" destdir="${build}" includes="Test.java"/>
  </target>
</project>


This is our compile target ,which compiles our code and also copies resources e.g. images, we can also create jar file using ant, which we are not doing here just for simplicity.

Imporant thing here is property ${ant.project.name} this is builtin propety provided by ant and its’s value is name of project defined by attribute “name” of proejct tag.

<copy> tag is used to copy files and <javac> tag is used to compile java code .

How do I debug build.xml?
if you see problem on your build or you are getting exception related to findiing files/directory or anything then you would like to know what’s going behind there are two option , run ant on verbose option , it will print lots of detail (I don’t prefer this) because of so much unwanted information but can be usefule in certain situation.

Second and my preffered way is good old “echo” way . use echo task to print values of properties, variables or printing simple message to check the work flow.

here are some example of using echo

<echo>Doing all</echo>
<echo message="Now creating directory source "/>
<echo level="warning" message ="Active configuration (config.active property) is not set - using default." />



How do I enforce ant to use file other than build.xml?

Normally when you run ant from any directory from command prompt it will look for file called build.xml in current directory; if it doesn’t find the file it will give error. If you have file named “custom_build.xml” you can instruct ant to use this file for building your application by using option “-f” e.g. ant –f custom_build.xml

Hope this would be useful let me know if you have any questions, doubt etc will be happy to answer.


Some other Tutorial you may like

2 comments :

Vandana Jaiswal said...

after creating the build.xml file and executing it i am getting an error "build.xml" does not exist build failed, please let me know on this, it is very much important for me to run the xml file to continue with my project

ranjit said...

i did all enviromental variable creation , but still facing the problem
C:\Users\ranramachandran>ant
'ant' is not recognized as an internal or external command,
operable program or batch file.

Post a Comment