| By Harry Klein | Article Rating: |
|
| March 15, 2005 12:00 AM EST | Reads: |
18,931 |
Apache Ant is a subproject being developed as part of the Jakarta project. Ant is a Java-based build tool which uses XML build files. Its main competitors are GNU Make, Jam, and NAnt. Many developers prefer Ant because it is environment-neutral, tightly integrated into Java, and faster than Make. XML build files are easier to create, read, and maintain than build files used with the Make utility (or other similar utilities).
The last CFDJ Ant article by John Ashenfelter (CFDJ, Vol. 6, issue 2) covered some basic Ant tasks that you would likely perform during the development process. Generalized, he used Ant to pull out the source code from VSS (Visual SourceSafe), make a build directory, and deploy it to the distribution directory.
In this article, I'll discuss some of Ant's more advanced features that are available in Ant's two task packages: the core task package and the optional task package. The core package contains tasks for building, packaging, and deploying projects, as well as tasks to execute SQL statements and tasks for integrating with Concurrent Versions System (CVS). The optional package extends Ant's functionality in a variety of ways, such as integrating with other source control systems and running unit tests using JUnit.
I will also provide an example of how to use the DbUnit Ant task. DbUnit is a JUnit extension targeted for database-driven projects that, among other things, puts your database into a known state between test runs.
The checksum sample application shows how to call the Ant framework through ColdFusion. Finally, I'll provide some Ant productivity tips.
Installing DbUnit
Read John Ashenfelter's Ant article or the Ant installation documentation located at http://ant.apache.org/manual/install.html in order to install Ant. Check that your environment variables are set correctly. Here is an example for Windows systems:
- Path: C:\apache-ant-1.6.2\bin
- ANT_HOME: C:\apache-ant-1.6.2
- JAVA_HOME: C:\j2sdk1.4.2\jre
The install process for DbUnit is very easy. First you have to download the DbUnit package from the DbUnit homepage (see resources). Then unpack the package and add the DbUnit jar to Ant's classpath. In a typical windows installation the path would be: C:\apache-ant-1.6.2\lib\ dbunit-2.1.jar
After this step you can use DbUnit by adding a <taskdef > element to your build script as follows:
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"/>
Use the task in the rest of the build file. I will explain this in more detail in the DbUnit Integration section.
A Typical Ant Project
In the first example I will walk through a simplified variant of an Ant file my company uses to create hotfix packages. See sys-con.com/coldfusion/sourcec.cfm (sourcecode1/build_cvs.xml) for the complete code; I will focus only on some important parts.
The file is divided into three parts: in the first two parts properties and patternsets are defined. The final part contains the Ant targets.
Properties
The properties are found first under the <project> element. These property elements are like variables. You can use the value of a property anywhere within a project and most commonly by tasks defined in <target> elements by using the expression ${property-name}.
For instance I am defining properties for the work directories, CVS settings, and ColdFusion cfencode options.
It is possible to define or overwrite properties when you invoke Ant at the command line with the syntax -Dproperty=value. For example, if you wished to set the value of "cvs_password" to "mypassword," you would type ant -Dcvs_password=mypassword. For security reasons, you should not hard code your password in the build file.
Patternsets
FileSets are groups of files. These files can be found in a directory tree starting in a base directory and are matched by patterns. Patterns can be grouped to sets and later be referenced by their ID attribute. They are defined via a patternset element, which appears later in the targets section nested into a FileSet. Patterns can be specified by nested <include>, or <exclude> elements.
In our example we are excluding unnecessary files through the patternset "patternExcludeUnneededDirectoriesAndFiles." We are also using a patternset with the iID "notEncoded". As the name says, files using this patternset should not be cfencoded.
Targets and Tasks
Target elements define a set of instructions for carrying out some kind of work. They may be compared to program functions that are themselves constructed of tasks (comparable to programming instructions). For instance, in our example, the target named "initDirs" (the <target> element with attribute name= initDirs) contains multiple mkdir tasks to create the work folders. The target element name is chosen by the creator, but the task names are fixed and match those defined in the Ant tag reference. The target "deploy" depends on several other targets, which means that if the target "deploy" is invoked, it will call the other targets first. When calling Ant, you can pass a target to run on the command line. For instance, by invoking Ant with the command line Ant deploy, you would run the target "deploy". If you call Ant without specifying a target, the target specified in the project's default attribute will be launched.
An Ant build file is a collection of targets dealing with a given stage of the project build or deployment. Here are the targets used in our sample build file:
- deploy: This is the default target.
- initDirs: Creates the work directories using the task <mkdir>.
- checkout: Exports the module from CVS. This target uses the cvspass task to write the cvsroot of the repository and the password to access it in the .cvspass file. The cvs task must authenticate on the CVS server, using data in the .cvspass file located in the home directory of the user. You can find details about the CVS task at http://ant.apache.org/manual/CoreTasks/cvs.html.
- dateFilter: Filters files by date using the tasks fileset and date (property $filter_date).
- deleteUnneededFilesAndDirectories: Deletes unneeded files and directories using the patternset defined in section two.
- encodeFiles: Encodes files using the task exec and the Macromedia command-line tool cfencode.exe. At the end of this target we use the patternset "notEncoded" to copy the unencoded custom tags over the encoded ones.
- buildDistributions: Copies the files to the distribution directory.
- zipFiles: Zips the files using the task zip. You can find details about the zip task at http://ant.apache.org/manual/CoreTasks/zip.html
- makeFileList: Builds file lists using the task exec and the DOS command line tool tree.exe.
- cleanup: Removes work directories.
DbUnit Integration
DbUnit is a test framework for developing unit tests inside your projects. The DbUnit task allows you to execute these tests from your Ant build file. Thus, using the DbUnit task, you can easily run all of your unit tests every time you build or deploy your project. DbUnit has the ability to export and import your database data to and from XML datasets. DbUnit also helps you to verify that your database data match expected set of values.
The following targets are used in the sample DbUnit build file, which you can find at sys-con.com/coldfusion/sourcec.cfm (sourcecode2/build_dbunit.xml):
- exportxml: Export database data to XML.
- exportdtd: Export database structure to DTD.
- exportdata: Partial database data export. Export two tables: table1, resulting from specified query and table2 entire content.
- importdata: Import data defined in file data.xml.
- deletedata: Delete data defined in file data.xml.
- comparedata: Compare partial data from query and xml file against the database.
I specified the Microsoft JDBC driver for Microsoft SQL Server "com.microsoft.jdbc.sqlserver.SQLServerDriver" for all DbUnit tasks. You can download this driver from the Microsoft Web site.
Building a Checksum Application with Ant and ColdFusion
This example (sourcecode3) consists of four files. See sys-con.com/coldfusion/sourcec.cfm for the complete code.
- ant_checksum.xml: Ant file containing only one target called "md5". This target uses the checksum task (s. http://ant.apache.org/manual/CoreTasks/checksum.html) to generate checksums for ColdFusion *.cfm and *.cfc files.
- index.cfm: User form, user can choose the directory where checksum files shall be generated.
- directorylist.cfm: Lists the entries in a directory tree in a format compatible with CFDirectory using recursion.
- ant.cfm: We receive the directory entered by the user in index.cfm. Then, after calling the customtag directorylist, we loop through the directory list entries. For every list entry a java file object is created:
<!--- set file to check --->
<cfobject type="JAVA" action="Create" name="oFile" class="java.io.File">
<cfset oFile.init(qFileList.path)>
Then we create a Ant Checksum object
<!--- checksum task --->
<cfobject type="JAVA" action="Create" name="oAntChecksum"
class="org.apache.tools.ant.taskdefs.Checksum">
and evaluate the checksum using the method eval()
<!--- evaluate checksum --->
<cfset oAntChecksum.setFile(oFile)>
<cfset sReturnval = oAntChecksum.eval()>
If the return value sReturnval is true, the file was unchanged, otherwise the file was changed. This simple application could be easily extended and used to check if files can be overwritten from a hotfix. This should only be the case when they were not changed by customers.
Ant Productivity Tips
Use Properties
By using properties you will make your build files reusable with minimal effort. In time, you can develop a collection of targets that you can reuse to develop new build files quickly. Use external property files to keep per-user settings out of the build files - especially passwords.
Use Relative File Paths
Relative paths are a good way to ensure your project's portability. Absolute file paths are much less flexible and will make changes in the directory structure of your project more painful than is necessary.
Issuing SQL Commands
Ant provides the SQL task for executing simple SQL statements as well as script files containing multiple SQL statements. The SQL task can be used for running SQL statements against any data source for which you have a Java database connectivity API (JDBC)-compliant driver
Get
The <get> task can fetch any URL, so it can be used to trigger remote server-side code during the build process, from remote server restarts to sending SMS/pager messages to the developer cellphones.
i18n
Internationalization is always trouble. Ant helps here with the native2ascii task which can escape out all non-ASCII characters into unicode. You can use this to write files which include strings (and indeed comments) in your own non-ASCII language and then use native2ascii to convert to ASCII.
Conclusion
Our team successfully introduced Ant and DbUnit to a client ColdFusion development environment. Since then, we've written several build files and automated processes that in the past took too much time and were error prone. Adding a bit of automation to the deployment process is a start to putting you in control of your development process. You should have less to worry about, a shorter build/test/deploy cycle, and more time to spend on new features.
Resources
Published March 15, 2005 Reads 18,931
Copyright © 2005 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Harry Klein
Harry Klein is cofounder and CTO at CONTENS Software GmbH, a leading supplier of enterprise content management software. He is a Certified Advanced ColdFusion developer and Microsoft MSCE.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Adobe Betas Target RIAs and Cloud Computing
- Adobe MAX 2009 Online
- Thinking of Flex in London
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Is Microsoft as Free as Open Source?
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- Adobe Flex Developer Earns $100K in New York City
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF



































