Welcome!

Industrial IoT Authors: Pat Romanski, William Schmarzo, Elizabeth White, Stackify Blog, Yeshim Deniz

Related Topics: Industrial IoT

Industrial IoT: Article

ANT: An Introduction by Example

ANT: An Introduction by Example

This article introduces the basic concepts of Ant and examines its built-in capabilities that can be used when building and testing J2EE applications in WebSphere. We also demonstrate how to extend Ant's function to interact with IBM WebSphere Application Server.

Ant and XML
The build process for an Ant user's project is defined through an XML buildfile. Since the buildfile is constructed with a common standard, it isn't necessary to learn - and adhere to - a new build tool syntax XML also makes the buildfile very readable and self-explanatory. This helps with the learning curve when you're getting up to speed with the project's build process. This article introduces the basic concepts of Ant and examines its built-in capabilities that can be used when building and testing J2EE applications in WebSphere. We also demonstrate how to extend Ant's function to interact with IBM WebSphere Application Server.

Ant and XML
The build process for an Ant user's project is defined through an XML buildfile. Since the buildfile is constructed with a common standard, it isn't necessary to learn - and adhere to - a new build tool syntax XML also makes the buildfile very readable and self-explanatory. This helps with the learning curve when you're getting up to speed with the project's build process.

Ant can be bundled easily with a software installation since it's supported on all Java-supported platforms and has a simple installation process. For example, code samples and tutorials that accompany application server software can also have Ant buildfiles to simplify their build-and-deploy process.

Ant is task-driven, with each task implemented by a Java class. Since it's based on Java, it's no longer necessary to maintain a buildfile per platform. Ant's configuration file is constructed once and run on any platform.

Ant provides a set of predefined tasks that make it quick and easy to get started. However, Ant isn't limited to these tasks: it's extensible through custom Java classes that implement a common interface. Not only are the tasks extensible, but Ant provides interfaces for creating custom build listeners.

A JAXP XML parser, along with a JDK (Java Developer's Kit), must be installed and configured on the machine that will be running Ant. If WebSphere Application Server is installed, then both the XML parser and the JDK are already configured. The Ant and the JAXP XML parser installables are downloadable at http://jakarta.apache.org/ant/index.html. Once downloaded and unpacked, only a few system variables remain to be set up before you can run Ant.

Running with Ant
When installation is complete, Ant is invoked by typing "ant" at a command prompt. Once invoked, Ant will locate a configuration file, build.xml, in the same directory from which it was invoked. By specifying the -find command-line parameter, Ant will attempt to locate the build.xml file from the current directory and, if not found, from each parent directory until the root directory has been searched. The configuration file isn't constrained to the name build.xml. Ant can be pointed to any configuration file using the -buildfile <file_name> command-line parameter.

The build.xml file is constructed with four main components (the relationship between them is displayed in Figure 1):

1. Project: Each buildfile has one project. The project is a unit of work that defines target(s), which consist of task(s). The project has three attributes: name, default, and basedir. Only the default attribute is required. The name attribute is a descriptive identifier for the project. The default attribute defines the name of the target that will be run by default when none is specified on the command line. The basedir attribute defines a directory from which all path calculations are made. If no basedir is specified, it defaults to the directory containing the buildfile. The basedir attribute can be overridden by a property with the name basedir.
2. Target: A target is a task or group of tasks that, when executed, do a particular job. Targets can be dependent on other targets, specified through the "depends" target attribute. This means that before the target is executed, Ant will execute each dependent target first, and, recursively, each of the dependent target's dependencies. After the dependencies have been executed, the tasks specified in the target will be invoked in the order in which they were defined.
3. Task: Each task corresponds to a Java class. A task can be a predefined Ant task, an optional Ant task, or a custom task. A task can have one or more attributes defined. These attributes can reference property values, which are resolved at runtime before the task is executed. All tasks have a name attribute that's used when Ant writes messages to a log.
4. Property (optional): A project can be associated with zero or more properties, which are name/value pairs or sets of properties from a file or resource that can be referenced in targets and tasks. The properties are defined via the property tag in the buildfile, or they can be defined through the command-line invocation of the buildfile. The value for the property provided at the command line will take precedence over the value specified in the buildfile. Additionally, Ant provides access to all of the system properties without having to define them as properties in the buildfile or on the command line.
Build.xml Example
Listing 1 is an example build.xml file. WebSphere Application Server AE and AEs v4.0 install with tutorials for learning the various aspects of application development on WebSphere (www.ibm.com/software/webservers/appserv/doc/v40/aee/index.html). In the advanced tutorial a CMP entity bean is assembled and deployed onto the WebSphere application server. For this example pretend the bean was altered and needs to be redeployed onto the server.

The project, named CMP11, defines the default target as do_all. When Ant is invoked without a specified target name, the do_all target is executed. This target doesn't define any tasks, but it does list dependencies. Before any of the tasks defined in the target are invoked, these dependencies will be invoked, and in the order in which they're listed: cleanUp, init, preDeploy_ejb, ejbDeploy, and, finally, hotDeploy.

Referenced throughout the project's targets and tasks are several properties that have been defined for this build. The properties define directory paths and names once, rather than in multiple locations throughout the project's targets and tasks. This minimizes the number of changes required when the source files are moved or when names are altered.

Notice that the hdDir property makes a reference to the "WAS_ HOME" property. While the property isn't defined in the buildfile, it is passed in on the command line via the -D<property_name> parameter so a system environment variable can be used to set it (see Figure 2). The last property defined uses the environment attribute of the property tag. This property is assigned the name "system" and allows all of the system environment variables to be accessed by system.<environment_var_name> in the targets and tasks.

The cleanUp target uses Ant predefined tasks to remove any directories and files that may be left over from previous runs of the build. The init target sets up the file system for the remainder of the build. It also uses several of Ant's predefined file system tasks such as copy and mkdir to manipulate the directories and files to initialize the project.

The preDeploy_ejb target consists of two tasks: compiling the source files and jarring the resulting class files with their deployment descriptor. It is invoked by Ant after the init target has completed. The first task specified in this target compiles the source files into a build directory that was created by the init target. The second task jars these compiled files into a JAR directory created by the init target. Since the preDeploy_ejb target relies on both of these directories being created by init, it has defined the init target as a dependency. Ant, however, is sophisticated enough to know that the init target was already executed as a dependency to the do_all target and therefore the init target is not invoked twice.

After the predeployment is finished, the ejbDeploy target is invoked. This target uses the exec task to invoke the ejbDeploy tool installed with WebSphere Application Server. This tool generates the deployment code for the specified .jar file - in this case the .jar file created during the predeployment. Since it generates deployed code from the .jar file created in the preDeploy_ejb target, the ejbDeploy target has preDeploy_ejb as a dependency.

The final target to be invoked is the hotDeploy target, which specifies two custom Ant tasks and a predefined copy Ant task. The two custom tasks involve stopping and starting an enterprise module that's specified as a project property at the beginning of the buildfile. After stopping the module, the new deployed .jar file is copied into the specified installed application folder and the module is then restarted. The hotDeploy function of the WebSphere Application Server reloads the EJBs specified in the new deployed .jar file.

Built-in Ant Tasks and Structures
Ant provides a set of powerful, built-in tasks ready for use. We've seen some of them in the sample build.xml file. Let's take a closer look.

  • javac: Searches the source directory recursively for Java source files and compiles them into Java class files in the target directory. The javac task compiles a source file only when there is no corresponding class file or the source file is newer than the class file.
  • exec: Provides a way to call operating system commands within Ant. Users can specify which command to execute based on OS type. In the sample build.xml file, ejbdeploy.sh is invoked on non-Windows platforms while ejbdeploy.bat is invoked on Windows platforms.
  • fileset: Not a task, rather an element that specifies a set of files. A fileset element can be nested in other tasks that operate on a selected set of files. A fileset element uses "includes" and "excludes" attributes to select files that (1) match a pattern, (2) don't match a pattern, or (3) match one pattern and not another. The patterns supported by Ant include '*', '?', and "**". The character '*' is used to match any number of characters in the filename; '?', to match any one character in the filename; "**", to match any levels of directory in the complete path of the files. The following example fileset element specifies all XML files under the source directory with names that don't begin with "test": <fileset name="non_test_xml" dir="${src} id="xmls"
    includes="**/*.xml"
    excludes="**/test*.xml"/>
  • copy: Copies a file to another file or a set of files to a directory. When copying a set of files, the set is specified by using the nested fileset element(s). A file is copied only when the source file is newer than its target or the target doesn't exist. The following demonstrates the copy task: <copy todir="${build}/META-INF">   <fileset dir="${source}/META-INF"/> </copy>
  • jar: Creates a .jar file. A user can include and/or exclude files from the .jar file via attributes of the jar task or nested fileset elements. The following example of the jar task creates a .jar file that includes all files specified in the nested fileset: <jar jarfile="${dist}/${app_name}.jar">  <fileset dir="${build}/${app_name}"   includes="**/*.class" /> </jar>

    Extending Ant
    Ant can be extended beyond built-in tasks with custom tasks and custom build listeners. Both are developed by extending the Ant framework. Let's investigate this in more detail.

    Writing Custom Ant Tasks
    Every task in Ant, including built-in tasks, is implemented as a Java class. Users can create a custom Ant task by creating a Java class that extends the class org.apache.tools.ant.Task. In addition, the following methods are usually required for simple tasks :

  • public void execute(): Throws org.apache.tools.ant.BuildException. The execute method needs to be overridden to perform the task.
  • public void set<Attrname>(<attrType> attr): If the custom task has attributes, a setter method is required for each attribute of the task. The setter method should be named 'set'<Attrname> where <Attrname> is the capitalized name of the attribute. At runtime Ant introspects on the Java class to determine the type of the attribute and converts the string in the buildfile to the proper type. For example, if the <attrType> is Boolean, Ant will convert the string "true," "yes," or "on" to the Boolean value true. See the Ant documents for more detail.
  • public Object create<Element>() or public void add<Element>(<Element> o): If the custom task allows nested elements, either a 'create'<Element> method or an 'add'<Element> method is required for each possible nested element where <Element> is the capitalized type of the nested element. If Ant encounters a nested element <Element> in the custom task while parsing the buildfile, Ant will look for the corresponding add<Element> or create<Element> in the Java class via introspection. For example, a fileset element can be nested in the built-in task copy. The Java class that implements the task copy defines method public void addFileset(FileSet set). When Ant parses a project and locates a custom task, Ant will generally:
    1. Create an instance of the implementation class.
    2. Invoke the 'create'<Element> or 'add'<Element> method for each nested element of type <element> when the buildfile is parsed.
    3. Invoke the 'set'<Attrname> methods for attributes named <attrname> at runtime.
    4. Invoke the 'execute' method when the task is executed.
    To use a custom task in a project, you have two options. The first is to use taskdef element to define the custom task in the scope of the project. This element has two attributes: the name of the task and the implementation class for the task. The second option is to add the name/value pair of the task name and the class name in the 'defaults.properties' file located in the $ANT_HOME/lib/ant.jar. This option makes the custom task available to all projects. In either case the Java implementation class needs to be included in the classpath at runtime. The following shows an example taskdef element and a sample entry in the 'defaults.properties' file. The taskdef element defines a custom task 'StopWSAppServer' in the scope of a project: <taskdef name="StopWSAppServer" classname="org.apache.tools.ant.taskdefs.optional.ejb.StopWSAppServer"/>

    The following entry in the 'defaults.properties' file defines the task 'StopWSAppServer' for all projects. stopWSAppServer=org.apache.tools.ant.taskdefs.optional.ejb.StopWSAppServer

    Listing 2 is an example of a custom Ant task named stopWSAppServer. The task stops a specified application server in WebSphere Application Server AE 4.0. The stopWSAppServer task requires two attributes: nodeName and appServerName. The methods setNodeName and setAppServerName are invoked by Ant to set the two attributes. The execute method is invoked when the task is executed.

    Writing Custom Ant Build Listeners
    Events can be generated by Ant at certain points when processing buildfiles. Custom listeners can be created and attached to an Ant build process to receive and process these events. Custom build listeners can create custom logs, send e-mails when the build has problems or when it's complete, or integrate Ant with a GUI or IDE.

    The events generated by Ant are org.apache.tools.ant.BuildEvent objects. The BuildEvent object provides access to information about the project and its components via the following methods:

    java.lang.Throwable getException() java.lang.String getMessage() int getPriority() Project getProject() Target getTarget() Task getTask()
    To create a custom Ant listener, the following listener interface must be implemented: org.apache.tools.ant.BuildListener. The BuildListener interface defines the following methods:
    public void buildFinished(BuildEvent e) public void buildStarted(BuildEvent e) public void messageLogged(BuildEvent e) public void targetFinished(BuildEvent e) public void targetStarted(BuildEvent e) public void taskFinished(BuildEvent e) public void taskStarted(BuildEvent e)
    Custom buildListeners are attached to an Ant process via two methods: the addBuildListener method on a Project object and via the command line. The following is an example of how to attach a BuildListener to the Ant process via the command line with the "listener" option.
    ant -listener org.apache.tools.ant.XmlLogger

    The XMLLogger is a listener installed with Ant that outputs log messages in XML format. The default listener displays the messages to the standard output.

    Listing 3 is an example of a simple custom Ant BuildListener. In this example the listener displays messages during the build to the standard output and sends an e-mail when the build has completed.

    *  *  *
    In conclusion, Ant is under continuous development. The next major release, Ant 2.0, will continue to improve on the three main characteristics of Ant: simplicity, understandability, and extensibility. It will provide better GUI support and integration with IDE tools. All tasks will be documented in XML files using a common DTD, which will make the tasks easier to understand. Ant 2.0 will make writing custom tasks easier by defining a clear contract between custom tasks and Ant, providing support for user-defined data types, and more.
  • More Stories By Ann Black

    Ann Black is currently a WebSphere developer for IBM. She has been focusing on J2EE technology and supporting software for the last year. Ann has a bachelor's degree in electrical engineering and is a Sun-certified programmer for the Java 2 Platform.

    More Stories By Yu Tang

    Yu Tang, a WebSphere developer at IBM, is experienced with Java, CORBA, and J2EE. He holds a bachelor's degree in physics and a master's degree in computer science.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    IoT & Smart Cities Stories
    Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
    The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
    The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
    We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
    The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
    There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
    Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
    At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
    Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
    BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.