Pages

May 02, 2017

Apache ANT Interview Questions And Answers

ANT stands for Another Neat Tool and is a Java based build tool from Apache Software Foundation. Apache Ant's build files are written in XML and they take advantage of being open standard, portable and easy to understand.

As a developer, we compile the code, package the binaries, deploy those binaries to the test server, test the changes and sometimes copy the code from one location to another. We can automate these tasks in a simplier way by using Apache Ant.


Features of Apache Ant
  • Ant is the most complete Java build and deployment tool available.
  • Ant is platform neutral and can handle platform specific properties such as file separators.
  • Ant can be used to perform platform specific tasks such as modifying the modified time of a file using 'touch' command.
  • Ant scripts are written using plain XML. If you are already familiar with XML, you can learn Ant pretty quickly.
  • Ant is good at automating complicated repetitive tasks.
  • Ant comes with a big list of predefined tasks.
  • Ant provides an interface to develop custom tasks.
  • Ant can be easily invoked from the command line and it can integrate with free and commercial IDEs
Installing Ant and Environment Setup
After installing Java Development Kit (JDK) and setting JAVA_HOME environment variable, download the latest version of ANT from http://ant.apache.org/bindownload.cgi

Create a new environment variable called ANT_HOME that points to the Ant installation folder (e.g c:\apache-ant-1.10.1). After this, append the path to the Apache Ant batch file to the PATH environment variable (e.g c:\apache-ant-1.10.1\bin).

To verify the successful installation of Apache Ant on your computer, run the below command:

C:\ >ant -version
Apache Ant(TM) version 1.10.1 compiled on April 16 2017


Build.xml
Usually, Ant's build.xml should reside in the base directory of the project. However there is no restriction on the file name or its location. All build files require the project element and at least one target element.

< ?xml version="1.0"? >
< project name="Hello World" default="info" >
    < target name="info" >
        < echo >Hello World!!< /echo >
    < /target >
< /project >


It will print 'Hello World!!' when you execute 'info'.
Where,
  • name : The Name of the project. (Optional)
  • default : The default target for the build script. A project may contain any number of targets. This attribute specifies which target should be considered as the default. (Mandatory)
  • basedir : The base directory (or) the root folder for the project. (Optional)
  • target: Its a collection of tasks that you want to run as one unit.

NOTE: There should be no blank line(s) or whitespace(s) before < ?xml version="1.0"? >, else you will get below error.

'The processing instruction target matching "[xX][mM][lL]" is not allowed.'

Targets can have dependencies on other targets. e.g
< ?xml version="1.0"? >
< project name="Hello World" default="info" >
    < target name="info1" >
        < echo >Hello World!! In Info1< /echo >
    < /target >
   
    < target name="info2" depends="info1" >
        < echo >Hello World!! In Info2< /echo >
    < /target >
< /project >


Target have following attributes:
  • name : The name of the target (Required)
  • depends : Comma separated list of all targets that this target depends on. (Optional)
  • description : A short description of the target. (optional)
  • if : Allows the execution of a target based on the trueness of a conditional attribute. (optional)
  • unless : Adds the target to the dependency list of the specified Extension Point. An Extension Point is similar to a target, but it does not have any tasks. (Optional)
To run the ant build file, go to the command prompt, navigate to the folder where the build.xml resides, and type 'ant info' or just type 'ant' (Both will work, because info is the default target in the build file).

Property Task In Ant
Ant does not allow declaring variables inside build.xml. It uses the property element, which allows you to specify the properties. These properties can be changed from one build to another or from one environment to another.

By default, Ant provides the following pre-defined properties that can be used in the build file:
ant.file : The full location of the build file.
  • ant.version : The version of the Apache Ant installation.
  • basedir : The basedir of the build, as specified in the basedir attribute of the project element.
  • ant.java.version : The version of the JDK that is used by Ant.
  • ant.project.name : The name of the project, as specified in the name atrribute of the project element.
  • ant.project.default-target : The default target of the current project.
  • ant.project.invoked-targets : Comma separated list of the targets that were invoked in the current project.
  • ant.core.lib : The full location of the Ant jar file.
  • ant.home : The home directory of Ant installation.
  • ant.library.dir : The home directory for Ant library files - typically ANT_HOME/lib folder.

Apart from these, we can define additional properties using the property element.

< ?xml version="1.0"? >
< project name="Hello World Project" default="info" >
   < property name="sitename" value="http://scrutinybykhimaanshu.blogspot.in/"/ >
   < target name="info" >
      < echo >You are at ${sitename} < /echo >
      < echo >Apache Ant version is ${ant.version}< /echo >
   < /target >  
< /project >


It will print:
[echo] You are at http://scrutinybykhimaanshu.blogspot.in/
[echo] Apache Ant version is Apache Ant(TM) version 1.9.2 compiled on July 8 2013

How to modify properties in ant?
No, you cannot modify the property, once its set. Ant sets properties by order, when something is set, the later same properties cannot overwrite the previous ones. This is opposite to your Java setters. You can say, properties in Ant are immutable. e.g:

< property name="sitename" value="http://scrutinybykhimaanshu.blogspot.in/"/ >
< property name="sitename" value="http://scrutinybykhimaanshu.blogspot.com/"/ >

  
Although sitename is overridden, the value will always remain 'http://scrutinybykhimaanshu.blogspot.in/'




How many ways we can set properties into build ant file?
We can use the combinations of all the below ways to set the properties in build files. But only one should be used at a time.
1. Supplying both the name and value attribute.
< property name=”src.dir” value=”src”/ >
2. Supplying both the name and refid attribute.
3. Setting the file attribute with the filename of the property file to load.
4. Setting the url attribute with the url from which to load the properties.
5. Setting the resource attribute with the resource name of the property file to load.
6. Setting the environment attribute with a prefix to use.

ANT Data Types
Ant provides a number of predefined data types, which are different from those that are available in the programming language, instead consider them as a set of services that are built into the product already.

Fileset : It represents a collection of files and is used as a filter to include or exclude files that match a particular pattern.

In the below example, the src attribute points to the source folder of the project. The fileset selects all .java files in the source folder except those contain the word 'Policy'. The case-sensitive filter is applied to the fileset which means a file with the name Medicalpolicy.java will not be excluded from the fileset.

< fileset dir="${src}" casesensitive="yes" >
   < include name="**/*.java"/ >
   < exclude name="**/*Policy*"/ >
< /fileset >


Pattern set : It is a pattern that allows to filter files or folders easily based on certain patterns. Patterns can be created using the following meta characters:
  • ? - Matches one character only.
  • * - Matches zero or many characters.
  • ** - Matches zero or many directories recursively.

e.g:
< patternset id="java.files.without.policies" >
   < include name="src/**/*.java"/ >
   < exclude name="src/**/*Policy*"/ >
< /patternset >


The patternset can then be reused with a fileset as follows:
< fileset dir="${src}" casesensitive="yes" >
   < patternset refid="java.files.without.policies"/ >
< /fileset >


Let's say you have the files:
  • bar.txt
  • src/bar.c
  • src/baz.c
  • src/test/bartest.c

Then the patterns:
  • *.c matches nothing (there are no .c files in the current directory)
  • src/*.c matches 2 and 3
  • */*.c matches 2 and 3 (because * only matches one level)
  • **/*.c   matches 2, 3, and 4 (because ** matches any number of levels)
  • bar.* matches 1
  • **/bar.*   matches 1 and 2
  • **/bar*.* matches 1, 2, and 4
  • src/ba?.c matches 2 and 3

File list: It is a data type, which is similar to the file set except the following differences:
  • filelist contains explicitly named lists of files and it does not support wild cards.
  • filelist data type can be applied for existing or non-existing files.

In the below example, the attribute webapp.src.folder points to the web application source folder of the project.
< filelist id="config.files" dir="${webapp.src.folder}" >
   < file name="applicationConfig.xml"/ >
   < file name="faces-config.xml"/ >
   < file name="web.xml"/ >
   < file name="portlet.xml"/ >
< /filelist >


Filter set : Using a filterset data type along with the copy task, you can replace certain text in all files that matches the pattern with a replacement value.

e.g, to append the version number to the release notes file :
< copy todir="${output.dir}" >
   < fileset dir="${releasenotes.dir}" includes="**/*.txt"/ >
   < filterset >
      < filter token="VERSION" value="${current.version}"/ >
   < /filterset >
< /copy >


The attribute output.dir points to the output folder of the project.
  • The attribute releasenotes.dir points to the release notes folder of the project.
  • The attribute current.version points to the current version folder of the project.
  • The copy task, as the name suggests, is used to copy files from one location to another.

Path : The path data type is commonly used to represent a class-path. Entries in the path are separated using semicolons or colons. However, these characters are replaced at the run-time by the executing system's path separator character.

The classpath is set to the list of jar files and classes in the project, as shown in the example below.

< path id="build.classpath.jar" >
   < pathelement path="${env.J2EE_HOME}/${j2ee.jar}"/ >
   < fileset dir="lib" >
      < include name="**/*.jar"/ >
   < /fileset >
< /path >


In this code:
The attribute env.J2EE_HOME points to the environment variable J2EE_HOME.
The attribute j2ee.jar points to the name of the J2EE jar file in the J2EE base folder.

How to delete files from a directory if it exists?
< delete >
    < fileset dir="${upperdir.which.exists}" >
      < include name="${classes.dir}/*.class" / >
    < /fileset >
< /delete >

The above code fails when directory does not exist and it uses implicit fileset, which is deprecated.
 
Creating JAR files with ANT is quite easy with the jar task. The commonly used attributes of the jar task are as follows:
  • basedir : The base directory for the output JAR file. By default, this is set to the base directory of the project.
  • compress : Advises Ant to compress the file as it creates the JAR file.
  • keepcompression : While the compress attribute is applicable to the individual files, the keepcompression attribute does the same thing, but it applies to the entire archive.
  • destfile : The name of the output JAR file.
  • duplicate : Advises Ant on what to do when duplicate files are found. You could add, preserve, or fail the duplicate files.
  • excludes : Advises Ant to not include these comma separated list of files in the package.
  • excludesfile : Same as above, except the exclude files are specified using a pattern.
  • inlcudes : Inverse of excludes.
  • includesfile : Inverse of excludesfile.
  • update : Advises Ant to overwrite files in the already built JAR file.
If we want to make the jar an executable jar file we need to add the manifest with the Main-Class meta attribute. e.g:
< target name="build-jar" >
   < jar destfile="${web.dir}/lib/util.jar"
      basedir="${build.dir}/classes"
      includes="scrutinyapp/util/**"
      excludes="**/TestIt.class" >
      < manifest >
         < attribute name="Main-Class" value="com.khs.util.ScrutinyUtil"/ >
      < /manifest >
   < /jar >
< /target >

Creating WAR files with ANT is extremely simple, and very similar to the creating JAR files task. The WAR task is an extension to the JAR task, but while creating the WAR, we can manipulate what goes into the WEB-INF/classes folder, and generating the web.xml file.

Since the WAR task is an extension of the JAR task, all attributes of the JAR task apply to the WAR task.
  • webxml : Path to the web.xml file
  • lib : A grouping to specify what goes into the WEB-INF\lib folder.
  • classes : A grouping to specify what goes into the WEB-INF\classes folder.
  • metainf : Specifies the instructions for generating the MANIFEST.MF file.

< target name="build-war" >
   < war destfile="scrutiny.war" webxml="${web.dir}/web.xml" >
      < fileset dir="${web.dir}/WebContent" >
         < include name="**/*.*"/ >
      < /fileset >     
      < lib dir="thirdpartyjars" >
         < exclude name="junit.jar"/ >
      < /lib >     
      < classes dir="${build.dir}/web"/ >
   < /war >  
< /target >


where,
web.dir variable refers to the source web folder, i.e, the folder that contains the JSP, css, javascript files etc.
The build.dir variable refers to the output folder - This is where the classes for the WAR package can be found.


Executing Java code with ANT: In the below example the java class takes in an argument (name) and prints it.
public class PrintMe {
    public static void main(String[] args) {
        String name = args[0];
        System.out.println("Name is : "+name);
    }
}

< ?xml version="1.0"? >
< project name="AntTest" default="notify" >
   < target name="notify" >
      < java fork="false" failonerror="yes" classname="PrintMe"  >
         < arg line="K Himaanshu Shuklaa.."/ >
      < /java >
   < /target >
< /project >

NOTE: If fork is true it executes a Java class within the running (Ant) VM else forks another VM if specified.

-K Himaanshu Shuklaa..

No comments:

Post a Comment