O'Reilly logo

Ant: The Definitive Guide, 2nd Edition by Steve Holzner

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 4. Deploying Builds

This chapter starts coverage of one of the things Ant does best: deployment. This chapter covers tasks to package applications for deployment like tar, gzip, and zip; tasks to prepare directories for deployment like delete and mkdir; and tasks to deploy applications like copy and move for local and network deployment, as well as ftp, telent, sshexec, and mail for remote deployment. You’ll see other deployment-related tasks, such as touch to set the deployed files’ modification dates to a specific value (as is done for commercial software deployments), fixcrlf to fix text file line endings (as in readme, .sh, .bat, .html, or .ini files) for different platforms, and more. Finally, you’ll learn how to handle build automation, setting up builds to run on their own, at a schedule of your choosing.

Tip

There’s more on deployment coming up in this book. Ant has a lot of support for deploying web applications, so much so that it’ll take more than just this chapter to cover. Chapter 8 covers how to package and deploy web applications, including using get (used to send administrative commands to web servers remotely), serverdeploy, war, and other Ant tasks designed to load web applications to various servers. Chapter 8 and part of Chapter 9 also specifically discuss how to deploy to Enterprise JavaBean© (EJB) application servers.

Packaging Applications for Deployment

We’re going to start with deployment tasks designed to package applications for deployment: tar, gzip, and zip. These are not the only way to package applications; the jar task was covered in Chapter 3 on Java Development, and the war task, a special form of the jar task for Web applications that makes allowances for files like the deployment descriptor web.xml, will be covered in Chapter 8.

Creating TAR Files

The tar task creates a TAR archive, handy for archiving files for distribution. This task is directory-based and, like other such tasks, forms an implicit FileSet that defines which files—relative to the basedir attribute setting—will be included in the archive.

If you set the compression attribute to gzip or bzip2, you can compress the output .tar file to the specified format. For instance, Example 4-1 compiles code and places the resulting Project.class file in a .tar.gz file, Project.tar.gz, by setting the compression attribute to gzip.

Example 4-1. Tarring a file (ch04/tar/build.xml)
<?xml version="1.0" ?>
<project default="main">

    <property name="message" value="Building the .tar.gz file." />
    <property name="src" location="source" />
    <property name="output" location="bin" />

    <target name="main" depends="init, compile, compress">
        <echo>
            ${message}
        </echo>
    </target>
  
    <target name="init">
        <mkdir dir="${output}" />
    </target>
  
    <target name="compile">
        <javac srcdir="${src}" destdir="${output}" />
    </target>
  
  <target name="compress">
        <tar 
            destfile="${output}/Project.tar.gz" 
            basedir="${output}" 
            includes="*.class" 
            compression="gzip"/>
  </target>
</project>

The attributes of this task appear in Table 4-1.

Table 4-1. The tar task’s attributes

Attribute

Description

Required

Default

basedir

Specifies the directory from which to get the files to TAR.

No

 

compression

Sets the compression method, if any. Legal values are none, gzip and bzip2.

No

none

defaultexcludes

Specifies if you want to use default excludes. Set to yes/no.

No

Default excludes are used.

destfile

Specifies the name of the TAR file you want to create.

Yes

 

excludes

Specifies the patterns matching files to exclude, as a comma- or space-separated list.

No

No files (except default excludes) are excluded.

excludesfile

Specifies the name of a file where each line is a pattern matching files to exclude.

No

 

includes

Specifies the patterns matching files to include, as a comma- or space-separated list.

No

All files are included.

includesfile

Specifies the name of a file where each line is a pattern matching files to include.

No

 

longfile

Specifies how you want to handle long file paths (more than 100 characters). Possible values are truncate, fail, warn, omit and gnu.

No

warn

Here’s another example that uses the Ant gzip task after the tar task to create Project.tar.gz:

<tar tarfile="${dist}/Project.tar" basedir="${output}"/>
<gzip zipfile="${dist}/Project.tar.gz" src="${dist}/project.tar"/>

This next example does the same thing, except that it excludes files from the beta directory and any todo.html files:

<tar tarfile="${dist}/Project.tar" basedir="${output}"
    excludes="beta/**, **/todo.html"/>
<gzip zipfile="${dist}/Project.tar.gz" src="${dist}/project.tar"/>

The tar task supports nested tarfileset elements. These are specially extended FileSet types that support all the fileset attributes, and the additional attributes you see in Table 4-2.

Tip

The tarfileset type gives you control over the access mode, username, and groupname to be applied to the TAR entries. This is handy, for example, when preparing archives for Unix systems where certain files need to have execute permissions.

Table 4-2. The additional tarfileset attributes

Attribute

Description

Required

Default

dirmode

Specifies a 3-digit octal string which gives the user and group using normal Unix conventions. Applies to directories only. Available since Ant 1.6.

No

755

fullpath

Using this attribute means the file in the fileset is written with this path in the compressed file.

No

 

group

Specifies the group name for the TAR item.

No

 

mode

Specifies a 3-digit octal string, which gives the user and group using normal Unix conventions. Applies to plain files only.

No

644

prefix

Specifies a path with which to prefix all files in the compressed file.

No

 

preserveLeadingSlashes

Specifies if you want to preserve leading slashes (/ ) in filenames.

No

false

username

Specifies the username for this TAR item.

No

 

This next, longer example uses GNU extensions for long paths and uses tarfileset elements to mark some files as executable (specifically, using Unix file mode 755, which means executable and readable by all, and writeable by the owner):

<tar longfile="gnu"
    destfile="${dist}" >
    <tarfileset dir="${bin}" mode="755" username="developer" group="ant">
        <include name="${bin}/bootstrap.sh"/>
        <include name="${bin}/build.sh"/>
    </tarfileset>
    <tarfileset dir="${dist}" username="developer" group="ant">
        <include name="${dist}/**"/>
        <exclude name="${dist}/*.sh"/>
    </tarfileset>
</tar>

Tip

Want to un-TAR a .tar archive? Ant has an untar task.

Compressing Using gzip and bzip2

The gzip and bzip2 tasks pack files using the GZip or BZip2 algorithms. Here’s an example that GZips a .tar file:

<gzip src="Project.tar" destfile="Project.tar.gz"/>

Here’s a similar example that BZips a .tar file:

<bzip2 src="Project.tar" destfile="Project.tar.bz2"/>

Tip

Ant supports gunzip and bunzip2 tasks for uncompressing archives.

The supported attributes for these tasks appear in Table 4-3.

Table 4-3. The gzip and bunzip2 tasks’ attributes

Attribute

Description

Required

destfile

Specifies the file you want to create.

Exactly one of destfile or zipfile

src

Specifies the file you want to GZip or BZip.

Yes

zipfile

Deprecated. Use destfile.

Exactly one of destfile or zipfile

Creating ZIP Files

The zip task creates ZIP files, useful for packaging files for deployment. The zip task is easy enough to use; here’s how to zip all files in the ${dist}/docs directory into docs.zip. If docs.zip doesn’t exist, it’s created; if it does, the files in it are updated:

<zip destfile="${dist}/docs.zip"
    basedir="${dist}/docs"
    update="true"
/>

This next example zips all files in the ${dist}/docs directory. Only .html files in the directory api will be zipped, and files with the name beta.html are excluded:

<zip destfile="${dist}/docs.zip"
    basedir="${dist}/docs"
    includes="api/**/*.html"
    excludes="**/beta.html"
/>

The attributes of this task appear in Table 4-4.

Tip

A JAR archive is a ZIP file with a manifest; if you don’t want a manifest in a JAR file, use zip instead of jar.

Table 4-4. The zip task’s attributes

Attribute

Description

Required

Default

basedir

Specifies the directory where the files you want to zip are.

No

 

compress

Specifies that you don’t want to store data but want to compresses it.

No

true

defaultexcludes

Specifies whether you want default excludes to be used or not (yes/no).

No

Default excludes are used

destfile

Specifies the ZIP file you want to create.

Exactly one of destfile or zipfile.

 

duplicate

Specifies what you want to do when a duplicate file is found. Valid values are add, preserve, and fail.

No

add

encoding

Specifies the character encoding you want to use inside the ZIP file.

No

The platform’s default character encoding.

excludes

Specifies the patterns matching files to exclude, as a comma- or space-separated list.

No

No files (except default excludes) are excluded.

excludesfile

Specifies the name of a file where each line is a pattern matching files to exclude.

No

 

filesonly

Stores only file entries.

No

false

includes

Specifies the patterns matching files to include, as a comma- or space-separated list.

No

All files are included.

includesfile

Specifies the name of a file where each line is a pattern matching files to include.

No

 

keepcompression

Preserves the compression as it has been in archives you’re compressing instead of using the compress attribute. Available since Ant 1.6.

No

false

update

Specifies whether you want to update or overwrite the destination file in case it exists.

No

false

whenempty

Specifies what you want to do when no files match. Possible values are fail, skip, and create.

No

skip

zipfile

Deprecated. Use destfile.

One of destfile or zipfile

 

This task supports any number of nested fileset elements to specify the files to be included in the ZIP file. The zip task supports any number of nested zipfileset elements, which support all the attributes of fileset (see Table 2-8) as well as the ones you see in Table 4-5.

Table 4-5. The additional zipfileset attributes

Attribute

Description

Required

Default

dirmode

Specifies a 3-digit octal string, which gives the user and group using normal Unix conventions. Applies to directories only.

No

755

filemode

Specifies a 3-digit octal string, which gives the user and group using normal Unix conventions. Applies to plain files only.

No

644

fullpath

Using this attribute means that the file in the fileset is written with this path in the compressed file.

No

 

prefix

Specifies a path to with which prefix all files in the compressed file.

No

 

src

Specifies a ZIP file instead of a directory as the source of files.

No

 

You can nest zipgroupfileset elements in a zip task. These elements allow you to add multiple ZIP files in the archive. The attributes for the zipgroupfileset type are the same as for the fileset type and include the extra attributes for zipfileset elements (see Table 4-5).

Tip

Because the zip task forms an implicit FileSet (dir becomes basedir), you can use nested include, exclude, and patternset elements.

This example zips all files in the docs directory into the docs/guide directory in the archive, adds the file readme.txt in the current directory as docs/readme.txt, and includes all the html files in examples.zip under docs/examples:

<zip destfile="${dist}/docs.zip">
    <zipfileset dir="docs" prefix="docs/guide"/>
    <zipfileset dir="${dist}" includes="readme.txt" fullpath="docs/readme.txt"/>
    <zipfileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/>
</zip>

Tip

Ant provides an unzip task if you want to decompress ZIP files.

Fixing Carriage Returns

If you’ve ever deployed documentation files from Unix to Windows or Windows to Unix, you’ve probably run into problems with line endings. Lines in Unix text files typically end with a newline (/n) while those in DOS and Windows typically end with a carriage return/line feed pair (/r/n). To modify text files before deploying them to other operating systems, use fixcrlf. Like other directory-based Ant tasks, this task forms an implicit FileSet and supports all attributes of fileset (dir becomes srcdir) as well as the nested include, exclude and patternset elements.

Say, for example, that you wanted to convert the end of line characters in Unix shell scripts (*.sh) to be uploaded from Windows to a Unix server to a linefeed, and remove any DOS-style end-of-file (EOF) characters (^Z). You could do that like this:

<fixcrlf srcdir="${src}"
    eol="lf" 
    eof="remove"
    includes="**/*.sh"
/>

Here’s how you might go the other way, replacing all end-of-line (EOL) characters with a cr-lf pair in DOS batch (.bat) files in preparation to downloading them to Windows:

<fixcrlf srcdir="${src}"
    eol="crlf"
    eof="add"
    includes="**/*.bat"
/>

This example converts all *.txt files according to the convention of the host operating system and replaces tabs with spaces:

<fixcrlf srcdir="${src}"
    tab="remove"
    includes="**/*.txt"
/>

Tip

As demonstrated by the previous example, fixcrlf is good for removing or inserting tabs. That’s useful because some software (e.g., Make) is finicky about tabs.

The attributes of this task appear in Table 4-6.

Table 4-6. The fixcrlf task’s attributes

Attribute

Description

Required

Default

cr

Deprecated. Use eol.

No

 

defaultexcludes

Specifies if you want to use default excludes or not Set to yes/no.

No

Default excludes are used.

destDir

Specifies where you want the modified files.

No

The value of srcDir.

encoding

Specifies the encoding of the files you’re working on.

No

The default JVM encoding.

eof

Specifies how you want to handle DOS end-of-file (^Z) characters. Possible values are:

add

Makes sure an EOF character is at the end of the file.

asis

Leaves EOF characters alone.

remove

Removes any EOF character found at the end.

No

The default is based on platform. In Unix, the default is remove. For Windows/DOS systems, the default is asis.

eol

Specifies how you want to handle end-of-line (EOL) characters. Possible values are:

asis

Leaves EOL characters alone.

cr

Converts all EOLs to a single CR.

lf

Converts all EOLs to a single LF.

crlf

Converts all EOLs to the pair CRLF.

mac

Converts all EOLs to a single CR.

unix

Converts all EOLs to a single LF.

dos

Converts all EOLs to the pair CRLF.

No

The default is based on platform. In Unix, the default is lf. For Windows/DOS systems, the default is crlf. For Mac OS, the default is cr.

excludes

Specifies the patterns matching files to exclude, as a comma- or space-separated list.

No

 

excludesfile

Specifies the name of a file where each line is a pattern matching files to exclude.

No

 

fixlast

Specifies whether you want to add an EOL to the last line of a processed file. Available since Ant 1.6.1.

No

true

includes

Specifies the patterns matching files to include, as a comma- or space-separated list.

No

 

includesfile

Specifies the name of a file where each line is a pattern matching files to include.

No

 

javafiles

Specifies if the file is a Java code file. Used with the tab attribute. Set to yes/no.

No

no

srcDir

Specifies where to find the files you want to fix.

Yes

 

tab

Specifies how you want to handle tab characters. Possible values are:

add

Converts sequences of spaces span a tab stop to tabs.

asis

Leaves tab and space characters alone.

remove

Converts tabs to spaces.

No

asis

tablength

Specifies the tab character interval. Possible values range from 2 to 80.

No

8

Warning

The output file is only written if it is a new file, or if it differs from the existing file. The idea is to prevent bogus rebuilds based on unchanged files that have been regenerated by this task.

Checking File Contents Using Checksums

A checksum is a numerical value corresponding to the contents of a file, and it can tell you if the copy of the file you’ve deployed is a good copy. This task lets you create an MD5 checksum for a file or set of files. Here’s an example using this task; in this case, I’m creating an MD5 checksum for Project.jar, which will be stored in a file named Project.jar.MD5:

<checksum file="Project.jar"/>

You can generate a similar checksum for the file after it’s been deployed to check if it’s OK.

Build files can be used to verify checksum values when testing a deployment; for example, you can generate an MD5 checksum for Project.jar, compare that value to a value you’ve hard-coded into a property named checksum, and set the property checksumOK if the two values match:

<checksum file="Project.jar" property="${checksum}" verifyProperty="checksumOK"/>

You can see the attributes of the checksum task in Table 4-7.

Table 4-7. The checksum task’s attributes

Attribute

Description

Required

Default

algorithm

Specifies the algorithm you want to use to compute the checksum.

No

MD5

file

Specifies the file you want to generate the checksum for.

One of file or at least one nested fileset element.

 

fileext

Specifies the extension of the file for the generated checksum.

No

Defaults to the algorithm name being used.

forceoverwrite

Specifies whether you want to overwrite existing files.

No

no

property

If verifyproperty is not set, property specifies the name of the property to hold the checksum value. If verifyproperty is set, property specifies the actual checksum value you expect.

No

 

provider

Specifies the algorithm provider.

No

 

readbuffersize

Specifies the size of the buffer the task should use when reading files, in bytes.

No

8192

todir

Specifies the directory where you want checksums to be written. Available since Ant 1.6.

No

Checksum files are written to the same directory as the source files.

totalproperty

Specifies the name of the property that you want to hold a checksum of all the generated checksums and file paths. Available since Ant 1.6.

No

 

verifyproperty

Specifies the name of the property to be set true or false depending upon whether the generated checksum matches the existing checksum.

No

 

Tip

The checksum task can contain nested fileset elements. By now, this should be old hat to you.

Setting Creation Time and Date

When you’re deploying files, you can set the creation date and time of those files to a single value to make the deployment look more professional (as you’ll usually see with commercial software). The touch task will do this for you; besides setting the creation time and date for a single file, you can do the same thing for whole directories of files if you include a fileset.

If you only specify a single file, its modification time and date is set to the current time and date:

<touch file="Project.jar"/>

Here’s an example that sets the modification time and date of all the files in ${src} to January 1, 2005, at 5:00 PM:

<touch datetime="01/01/2005 5:00 pm">
    <fileset dir="${src}"/>
</touch>

Tip

If the file you’re touching doesn’t exist, touch will create it for you, which is one of the few ways you can use Ant to create empty files (you can create files with text in them with the echo task, using the file attribute). Want to give the file a name that’s guaranteed to be unique? Use Ant’s tempfile task—for example, <tempfile property="temp.file" /> will store the unique name of a file in the temp.file property, and <touch file="${temp.file}" /> will create that file.

You can see the attributes of this task in Table 4-8.

Table 4-8. The touch task’s attributes

Attribute

Description

Required

datetime

Specifies the new modification time of the file. Use the formats MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM.

No

file

Specifies the name of the file whose time and/or date information you want to change.

Yes, unless you use a nested fileset element.

millis

Specifies the new modification time of the file, given in epoch milliseconds (that is, since midnight, Jan 1, 1970).

No

The touch task can contain nested fileset elements to touch multiple files at once.

Preparing to Deploy

Ant supports several tasks for setting up a deployment environment, such as delete and mkdir. Both these tasks can be used locally or on a network to set up the directory structure you need to deploy applications.

Tip

If you want to create and delete directories remotely, take a look at the ftp task, coming up later in this chapter.

Deleting Existing Files

When deploying, delete is great to clean up a previous installation or to clean deployment directories before installing. This task deletes a single file, a directory and all its files and subdirectories, or a set of files specified by one or more FileSets.

Using this task, you can delete a single file:

<delete file="/lib/Project.jar"/>

Or you can delete an entire directory, including all files and subdirectories:

<delete dir="${dist}"/>

You can use filesets:

<delete includeEmptyDirs="true">
    <fileset dir="${dist}"/>
</delete>

You’ve seen delete at work in various places throughout the book, as in the build file in the input folder for Chapter 3s code (repeated in Example 4-2), where the user is asked for confirmation before deleting anything.

Example 4-2. Using the delete task (ch03/input/build.xml)
<?xml version="1.0" ?>
<project default="main">

    <property name="message" value="Building the .jar file." />
    <property name="src" location="source" />
    <property name="output" location="bin" />

    <target name="main" depends="init, compile, compress">
        <echo>
            ${message}
        </echo>
    </target>
  
    <target name="init">
        <input
            message="Deleting bin directory OK?"
            validargs="y,n"
            addproperty="do.delete"
        />
        <condition property="do.abort">
            <equals arg1="n" arg2="${do.delete}"/>
        </condition>
        <fail if="do.abort">Build aborted.</fail>
        <delete dir="${output}" />
        <mkdir dir="${output}" />
    </target>
  
    <target name="compile">
        <javac srcdir="${src}" destdir="${output}" />
    </target>
  
  <target name="compress">
        <jar destfile="${output}/Project.jar" basedir="${output}" includes="*.class" />
  </target>
</project>

Tip

If you use this task to delete temporary files created by editors or other software and it doesn’t work, try setting the defaultexcludes attribute to no.

You can see the attributes of this task in Table 4-9.

Tip

The includes, includesfile, exclude, and excludesfile attributes are deprecated and are being replaced by fileset. This makes me suspect that other tasks will follow this same pattern.

Table 4-9. The delete task’s attributes

Attribute

Description

Required

Default

defaultexcludes

Specifies if you want to use default excludes. Set to yes/no.

No

Default excludes are used.

dir

Specifies the name of a directory to delete. All its files and subdirectories will be deleted.

At least one of file or dir (unless a fileset element is specified).

 

excludes

Deprecated. Use a fileset element. Specifies the patterns matching files to exclude, as a comma- or space-separated list.

No

No files (except default excludes) are excluded.

excludesfile

Deprecated. Use a fileset element. Specifies the name of a file where each line is a pattern matching files to exclude.

No

 

failonerror

Specifies if you want an error to stop the build. Only used if if quiet is false.

No

true

file

Specifies the file you want to delete.

At least one of file or dir (unless a fileset element is specified).

 

includeEmptyDirs

Specifies if you want to delete empty directories when using file sets.

No

false

includes

Deprecated. Use a nested fileset element. Specifies the patterns matching files to include, as a comma- or space-separated list.

No

All files are included.

includesfile

Deprecated. Use a nested fileset element. Specifies the name of a file where each line is a pattern matching files to include.

No

 

quiet

Suppresses most diagnostic messages.

No

 

verbose

Specifies that you want to show the name of each deleted file (true/false).

No

false

The delete task can contain nested fileset elements.

Tip

Here’s something you might not have expected: empty directories are not deleted by default. To remove empty directories, use the includeEmptyDirs attribute.

Creating New Directories

Want to create the directory structure for local or network deployment? Use mkdir. This one’s so important that you’ve seen it in use since Chapter 1. And it’s easy to use with only one attribute, as you can see in Table 4-10.

Table 4-10. The mkdir task’s attributes

Attribute

Description

Required

dir

Specifies the directory you want to create

Yes

Want to create a directory? Just do it:

<mkdir dir="${dist}"/>

Tip

Just realized that you’ve asked mkdir to create a directory whose parent directories don’t exist? That’s not a problem since mkdir creates parent directories as needed.

Deploying Applications

As you’d expect, Ant excels at deploying applications, and there are a number of tasks to choose from. You’ve saw the javac task’s destdir attribute for deployment back in Chapter 1. In this section, you’ll see copy, move, ftp, telnet, and sshexec.

The copy and move tasks are useful for local and network deployments, and tasks like ftp are great for remote deployments. Additionally, Chapter 8 will cover deployment to web servers with tasks like get, which you can use to send administrative commands to servers like Tomcat (I’ll cover Tomcat’s built-in custom Ant tasks), and serverdeploy.

Tip

Want to get a file’s name without the path attached? Pass the filename to the basename task. Want to get just the path? Use dirname. The pathconvert task converts a nested path or reference to a Path, FileSet, DirSet, or FileList into a path (automatically adjusted for the target platform) and stores the result in a given property.

Deploying by Copying

This task copies a file, or a fileset, to a new file or a new directory. This is Ant’s most basic deployment task for local and network deployment. Here are a few examples, starting with copying just one file:

<copy file="file.txt" tofile="backup.txt"/>

This example copies a file to a new location:

<copy file="file.txt" todir="../backup"/>

This example copies an entire directory to a new location:

<copy todir="../backup">
    <fileset dir="${src}"/>
</copy>

This copies a set of files to a new directory:

<copy todir="../backup">
    <fileset dir="src">
        <include name="**/*.java"/>
    </fileset>
</copy>

Want to copy files and change their names? Use a mapper element like this:

<copy todir="../backup">
    <fileset dir="src"/>
    <mapper type="glob" from="*" to="*.old"/>
</copy>

Here’s how to copy a set of files to a directory, replacing @TODO@ with "DONE" in all copied files:

<copy todir="../backup">
    <fileset dir="src"/>
    <filter set>
        <filter token="TODO" value="DONE"/>
    </filter set>
</copy>

Warning

In Unix, file permissions are not retained when files are copied; files end up with the default UMASK permissions instead. If you need a permission-preserving copy function, use the system copy utilities—see the exec task in Chapter 7 (you’d use <exec executable="cp" ... > here). Or use the chmod task, coming up in this chapter, after the copy.

Example 4-3 uses copy to copy a documentation file to make sure it’s included in the final JAR for a project and then deploys the JAR file to a directory named user.

Example 4-3. Using the copy task (ch04/copy/build.xml)
<?xml version="1.0" ?>
<project default="main">

    <property name="message" value="Deploying the .jar file." />
    <property name="src" location="source" />
    <property name="output" location="bin" />
    <property name="dist" location="user" />

    <target name="main" depends="init, compile, compress, deploy">
        <echo>
            ${message}
        </echo>
    </target>
  
    <target name="init">
        <mkdir dir="${output}" />
        <mkdir dir="${dist}" />
    </target>
  
    <target name="compile">
        <javac srcdir="${src}" destdir="${output}" />
    </target>
  
    <target name="compress">
        <copy todir="${output}" file="${src}/readme.txt"/>
        <jar destfile="${output}/Project.jar" basedir="${output}">
            <include name="*.class"/>
            <include name="*.txt"/>
        </jar>
    </target>

    <target name="deploy">
        <copy todir="${dist}">
            <fileset dir="${output}">
                <exclude name="*.java"/>
                <exclude name="*.class"/>
                <exclude name="*.txt"/>
            </fileset>
        </copy>
    </target>

</project>

You can see the attributes of this task in Table 4-11.

Table 4-11. The copy task’s attributes

Attribute

Description

Required

Default

enablemultiplemappings

Specifies that you want to use multiple mapper elements. Available since Ant 1.6.

No

false

encoding

Specifies the encoding to use. For use when copying files using filters.

No

Defaults to default JVM encoding.

failonerror

Specifies whether you want the task to fail if there is an error.

No

true

file

Specifies the file you want to copy.

Yes, unless a nested fileset element is used.

 

filtering

Specifies whether you want to use filtering. Nested filterset elements will always be used; you don’t have to set this attribute to true for that.

No

false

flatten

Specifies you want to ignore the directory structure of source files, copying all files into the directory given by the todir attribute.

No

false

includeEmptyDirs

Specifies you want to copy any empty directories as well.

No

true

outputencoding

Specifies the encoding you want to use when writing files. Available since Ant 1.6.

No

Defaults to the value of the encoding attribute if given, or the default JVM encoding otherwise.

overwrite

Specifies whether you want to overwrite existing files.

No

false

preservelastmodified

Specifies you want copied files to have the same modified time as the source files.

No

false

todir

Specifies the directory the files should be copied to.

If you use the file attribute, tofile or todir can be used. If you use nested fileset elements and if the number of files is more than 1 or if only the dir attribute is specified in the fileset, then only todir is allowed.

 
tofile

Specifies the file you want to copy to.

If you use the file attribute, tofile or todir can be used. If you use nested fileset elements and if the number of files is more than 1 or if only the dir attribute is specified in the fileset, then only todir is allowed.

 
verbose

Specifies you want to see filenames displayed as the files are being copied.

No

false

Tip

By default, files are only copied if the source file is newer than the destination file or when the destination file does not exist. However, you can explicitly overwrite files with the overwrite attribute.

You can use fileset elements inside copy elements to create a fileset to copy. If you want to use a fileset, the todir attribute must be set. You can use nested mapper elements, and filter set elements and the copy task supports nested FilterChains.

Warning

If you use filters in your copy operation, limit the operation to text files. Binary files will be corrupted by that kind of copy operation. This is true whether the filters are implicitly defined by the filter task or explicitly provided to the copy operation as filter sets.

Moving Files

The move task moves a file (copies and then deletes the original) to a new file or a new directory or it moves sets of files to a new directory. The attributes and nested elements are the same as for copy (see Table 4-11 and related sections).

Tip

By default, the destination file is overwritten if it already exists. When overwrite is turned off, files are only moved if the source file is newer than the destination file, or when the destination file does not exist.

Here’s an example that moves a single file (the net result is that the file is renamed):

<move file="file.txt" tofile="file.backup"/>

Here’s how to move a directory to a new directory:

<move todir="source">
    <fileset dir="backup"/>
</move>

Example 4-4 uses move to deploy the files it creates.

Example 4-4. Moving a file (ch04/move/build.xml)
<?xml version="1.0" ?>
<project default="main">

    <property name="message" value="Deploying the .jar file." />
    <property name="src" location="source" />
    <property name="output" location="bin" />
    <property name="dist" location="user" />

    <target name="main" depends="init, compile, compress, deploy">
        <echo>
            ${message}
        </echo>
    </target>
  
    <target name="init">
        <mkdir dir="${output}" />
        <mkdir dir="${dist}" />
    </target>
  
    <target name="compile">
        <javac srcdir="${src}" destdir="${output}" />
    </target>
  
  <target name="compress">
        <jar destfile="${output}/Project.jar" basedir="${output}" 
            includes="*.class" />
  </target>

  <target name="deploy">
    <move todir="${dist}">
      <fileset dir="${output}">
          <exclude name="*.java"/>
          <exclude name="*.class"/>
      </fileset>
    </move>
  </target>

</project>

Tip

For more examples, look at the section “Deploying By Copying”.

Deploying Remotely Using FTP

The ftp task is handy for remote deployment. This task can send, receive, list, delete files, and create directories. This is one of Ant’s optional tasks, so you’ll need two JAR files, which you place in the Ant lib directory: jakarta-oro.jar (available from http://jakarta.apache.org/oro/) and commons-net.jar (available from http://jakarta.apache.org/commons/net/index.html).

Warning

If you want to use this task with MS FTP servers, you need a version of commons-net.jar and jakarta-oro.jar released after 02/01/2004, or a release of commons-net.jar after 1.1.0 and jakarta-oro.jar after 2.0.8.

Here’s an example that deploys the results of a build to the directory /cgi-bin on a remote server. Since it’s a bad idea to hardcode the username and password in build files, I’ll set those as properties on the command line (you can use the input task here) using the properties name and password:

%ant -Dname=Steve -Dpassword=let_me_in

The build file is shown in Example 4-5. Before running the file, supply the IP address of the server by changing the value of the server attribute from “000.000.000.000” to the IP address of your server or use the name of the server, like “ftp.apache.org.” Though you usually supply an action attribute telling ftp what to do, the default action is to send files (action="send“), so you can omit action here.

Example 4-5. Using ftp (ch04/ftp/build.xml)
<?xml version="1.0" ?>
<project default="main">

    <property name="message" value="Deploying the .jar file." />
    <property name="src" location="source" />
    <property name="output" location="bin" />

    <target name="main" depends="init, compile, compress, deploy">
        <echo>
            ${message}
        </echo>
    </target>
  
    <target name="init">
        <mkdir dir="${output}" />
    </target>
  
    <target name="compile">
        <javac srcdir="${src}" destdir="${output}" />
    </target>
  
    <target name="compress">
        <jar destfile="${output}/Project.jar" basedir="${output}">
            <include name="*.class"/>
            <include name="*.txt"/>
        </jar>
    </target>

    <target name="deploy">
        <ftp server="000.000.000.000" binary="true" verbose="true"
            userid="${name}" password="${password}" remotedir="/cgi-bin">
            <fileset dir="${output}">
                <exclude name="*.java"/>
                <exclude name="*.class"/>
                <exclude name="*.txt"/>
            </fileset>
        </ftp>
    </target>

</project>

Here’s what running this build file looks like in Windows when uploading the results of a build to a remote server:

C:\ant\ch04\ftp>ant -Dname=steven -Dpassword=let_me_in
Buildfile: build.xml

init:
    [mkdir] Created dir: C:\ant\ch04\ftp\bin

compile:
    [javac] Compiling 1 source file to C:\ant\ch04\ftp\bin

compress:
      [jar] Building jar: C:\ant\ch04\ftp\bin\Project.jar

deploy:
      [ftp] sending files
      [ftp] transferring C:\ant\ch04\ftp\bin\Project.jar
      [ftp] 1 files sent

main:
     [echo]
     [echo]             Deploying the .jar file.
     [echo]

BUILD SUCCESSFUL
Total time: 10 seconds

That’s it; you’ve deployed the results of the build remotely. Very cool!

Tip

If you want to build in delay times to take into account delays in getting responses from a server, use the Ant waitfor task. You can use the sleep task for this purpose.

To retrieve files from the server using ftp, you set action to get, the remotedir attribute to the remote directory, and the dir attribute to the directory you want the retrieved files stored in locally:

<ftp action="get"
    server="000.000.000.000"
    remotedir="/cgi-bin"
    userid="${name}"
    password="${password}">
    <fileset dir="docs">
        <include name="**/*.html"/>
    </fileset>
</ftp>

To delete files, set action to “del”:

<ftp action="del"
    server="000.000.000.000"
    remotedir="/cgi-bin"
    userid="${name}"
    password="${password}">
    <fileset>
        <include name="**/*.html"/>
    </fileset>
</ftp>

To list files, set action to “list;” here’s how to store the listing of files in the remote /cgi-bin directory in a file named file.list:

<ftp action="list"
    server="000.000.000.000"
    remotedir="/cgi-bin"
    userid="${name}"
    password="${password}"
    listing="ftp.list">
    <fileset>
        <include name="**"/>
    </fileset>
</ftp>

Here’s how to create a directory, /cgi-bin, by setting action to “mkdir:”

<ftp action="mkdir"
    server="000.000.000.000"
    remotedir="/cgi-bin"
    userid="${name}"
    password="${password}"/>

Tip

You can remove directories; set action to rmdir.

You can see the attributes of this task in Table 4-12.

Table 4-12. The ftp task’s attributes

Attribute

Description

Required

Default

action

Specifies the ftp action you want to perform. Possible values: put, get, del, list, chmod, mkdir and rmdir.

No

send

binary

Specifies the transfer mode. Possible values: binary-mode (yes) or text-mode (no).

No

yes

chmod

Specifies the file permissions for new or existing files (Unix only).

No

 

depends

Specifies you want to transfer only new or changed files. Set to yes/no.

No

no

ignoreNoncriticalErrors

Specifies you want to allow the task to continue despite some non-fatal error codes.

No

false

listing

Specifies a file to write output from the “list” action.

Required for the “list” action, but ignored otherwise.

 

newer

The same as the depends attribute.

No

 

passive

Specifies you want to use passive transfers.

No

no

password

Specifies the login password for the FTP server.

Yes

 

port

Specifies the port of the FTP server.

No

21

preservelastmodified

Specifies whether you want to give downloaded files the same modified time as the original files.

No

false

remotedir

Specifies a directory on the FTP server you want to use.

No

 

separator

Specifies the directory separator used on the target FTP server.

No

/

server

Specifies the address of the FTP server.

Yes

 

skipFailedTransfers

Specifies unsuccessful transfers should be skipped (with a warning).

No

false

timediffauto

Specifies if to make this task calculate the time difference between you and server. Available in Ant 1.6 or later.

No

 

timediffmillis

Specifies the number of milliseconds between times on the target machine compared to the local machine. Available since Ant 1.6.

No

 

umask

Specifies the default file permission (unix only).

No

 

userid

Specifies the login you want to use on the FTP server.

Yes

 

verbose

Specifies whether you want to see information on each file as it’s transferred. Set to yes/no.

No

no

Tip

The condition task lets you probe if remote systems are available before attempting an FTP operationYou can use two nested elements in condition: http (which can test can probe for remote servers) and socket (which can send messages to remote servers).

The ftp task supports any number of nested fileset elements, which is how you specify the files to be retrieved, deleted, or listed, or whose mode you want to change.

Deploying Remotely Using Telnet

Ant includes a telnet task that you can use when deploying remotely. For security reasons, Telnet is losing popularity (in favor of SSH), but I’ll take a look at telnet, followed by the sshexec task. This is one of Ant’s optional tasks, so you’ll need commons-net.jar (available from http://jakarta.apache.org/commons/net/index.html) in the Ant lib directory.

This task uses nested read elements to indicate strings to wait for and write elements to specify text to send. Here’s an example that connects to a server, and asks for a listing of the directory /home/steven:

<telnet userid="steven" password="let_me_in" server="000.000.000.000">
     <read>/home/steven</read>
     <write>ls</write>
</telnet>

You can see the attributes of this task in Table 4-13.

Table 4-13. The telnet task’s attributes

Attribute

Values

Required

Default

initialCR

Specifies that you want to send a carriage return after connecting to the server.

No

no

password

Specifies the login password you want to use on the Telnet server.

Yes, if userid is specified.

 

port

Specifies the port on the Telnet server to use.

No

23

server

Specifies the address of the remote Telnet server you want to use.

Yes

 

timeout

Specifies a default timeout for Telnet actions (in seconds).

No

No timeout

userid

Specifies the username to use to log into the Telnet server.

Yes, if password is specified.

 

Deploying Remotely Using SSH

The more secure SSH protocol is replacing Telnet in general use, and Ant 1.6 added the sshexec task to execute SSH commands on a remote system. This is an optional task, so you’ll need jsch.jar (which you can get at http://www.jcraft.com/jsch/index.html) in the Ant lib directory. Here’s an example that runs a command, touch, on a remote machine, using sshexec:

<sshexec host="000.000.000.000"
    username="${name}"
    password="${password}"
    command="touch index.html"/>

You can find the attributes of this task in Table 4-14.

Tip

See the scp task for copying files for deployment to web servers using SSH in Chapter 8.

Table 4-14. The sshexec task’s attributes

Attribute

Description

Required

Default

append

Specifies if you want the output file to be appended to or overwritten.

No

false

command

Specifies the command to run remotely.

Yes

 

failonerror

Specifies whether you want to stop the build if there are errors.

No

true

host

Specifies the host you want to work with.

Yes

 

keyfile

Specifies the name of a file holding a private key.

Yes, if you are using key-based authentication.

 

knownhosts

Specifies the known hosts file. Used to check the identity of remote hosts. Must be an SSH2 format file.

No

${user.home}/.ssh/known_hostswn_hostts

output

Specifies the name of a file in which you want output written.

No

 

outputproperty

Specifies the name of a property in which you want output written.

No

 

passphrase

Specifies a passphrase you want to use for your private key.

No

“”

password

Specifies the password to use for SSH.

No

 

port

Specifies the port to connect to.

No

22

timeout

Specifies whether you want the operation stopped if it timed out (in milliseconds).

No

0 (wait forever)

trust

Specifies if to trust all unknown hosts if set to “yes.”

No

no

username

Specifies the username you want to use.

Yes

 

Deploying Remotely Through Email

You can deploy using email with the mail task, attaching files you want to deploy (attachments can be sent using the files attribute or nested fileset elements). You’ll need access to an SMTP server, which you specify in the mailhost attribute and need two JAR files in the Ant lib directory: mail.jar (which you can get from http://java.sun.com/products/javamail/) and activation.jar (which you can get from http://java.sun.com/products/javabeans/glasgow/jaf.html).

Here’s an example, where the results of a build are deployed as an attachment to an email message. This email has the subject “New Build”, the message body “Here is the new build.”, and has the build’s newly created .tar.gz files attached:

<target name="deploy">
    <mail mailhost="smtp.isp.com" mailport="1025" subject="New Build">
        <from address="developer@isp.com"/>
        <replyto address="developer@isp.com"/>
        <to address="list@xyz.com"/>
        <message>Here is the new build.</message>
        <fileset dir="dist">
            <includes name="**/*.tar.gz"/>
        </fileset>
    </mail>
</target>

Now you’re deploying via email using Ant. You can see the attributes of the mail task in Table 4-15.

Table 4-15. The mailTask’s attributes

Attribute

Description

Required

Default

bcclist

List of addresses to send a blind copy of the email to. A comma-separated list.

At least one of tolist, cclist, bcclist, or the equivalent elements (to, cc, or bcc).

 

cclist

List of addresses to send a copy of the email to. A comma-separated list.

At least one of tolist, cclist, bcclist, or the equivalent elements (to, cc, or bcc).

 

charset

Specifies the character set you want to use in the email.

No

 

encoding

Specifies the encoding to use. Possible values are mime, uu, plain, or auto.

No

auto

failonerror

Specifies whether you want to stop the build if there are errors.

No

true

files

Specifies files you want to send as attachments. Use a comma-separated list. You can use nested fileset elements.

No

 

from

Specifies the email address of the sender.

Either a from attribute or a from element.

 

includefilenames

Specifies whether you want to include filename(s) before file contents.

No

false

mailhost

Specifies the hostname of the SMTP server.

No

localhost

mailport

Specifies the TCP port of the SMTP server to use.

No

25

message

Specifies the email’s body.

One of message, messagefile, or a message element.

 

messagefile

Specifies a file to send as the email’s body.

One of message, messagefile, or a message element.

 

messagemimetype

Specifies the type of the message’s content.

No

text/plain

password

Specifies the password for SMTP authorization.

Yes, if SMTP authorization is required on your SMTP server.

 

replyto

Specifies the reply-to address.

No

 

ssl

Specifies if you want to use TLS/SSL.

No

 

subject

Specifies the email’s subject.

No

 

tolist

Specifies a list of recipients. A comma-separated list.

At least one of tolist, cclist, bcclist, or the equivalent elements (to, cc, or bcc).

 

user

Specifies the username used to log into the SMTP server.

Yes, if SMTP authorization is required on your SMTP server.

 

The mail task can take nested to, cc, bcc, from, and replyto elements, which hold email addresses. Here are the attributes of these elements (these attributes are common across all these elements):

address

Specifies the email address

name

Specifies the display name for the email address

In addition, the nested message element sets the message to include in the email body. Here are the attributes of this element (all are optional):

charset

Specifies the character set used in the message

mimetype

Specifies the content type of the message

src

Specifies the file to use as the message

You can use email to send the results of a build with the mail logger, which is useful if you’ve set up unattended nightly builds with utilities like at in Windows or crontab in Unix (see Chapter 7 for coverage of both of these). Here’s how you use this logger:

%ant -logger org.apache.tools.ant.listener.MailLogger

You set these properties in the build file to set up the email you want sent:

MailLogger.mailhost

Specifies the mail server to use (default: localhost)

MailLogger.port

Specifies the default port for SMTP (default: 25)

MailLogger.from

Specifies the mail “from” address (required)

MailLogger.failure.notify

Specifies if to send on failure (default: true)

MailLogger.success.notify

Specifies if to send on success (default: true)

MailLogger.failure.to

Specifies the address to send failure messages to (required if failure mail to be sent)

MailLogger.success.toSpecifies

The address to send success messages to (required if success mail to be sent)

MailLogger.failure.subject

Specifies the subject of failed build (default: “Build Failure”)

MailLogger.success.subject

Specifies the subject of successful build (default: “Build Success”)

Setting File Protections with chmod

The chmod task changes the permissions of a file or files, and it’s useful in deployment after you’ve got your files deployed in case you need to set file permissions. You set the permissions in Unix style (just as the arguments for the Unix chmod command).

Here’s an example that makes run.sh readable, writable and executable for the owner on a Unix system, and readable and executable for others:

<chmod file="${dist}/run.sh" perm="755"/>

This makes all .sh files in and below ${dist} readable and executable for anyone on a Unix system:

<chmod dir="${dist}" perm="ugo+rx" 
    includes="**/*.sh"/>

You can see the attributes for this task in Table 4-16.

Warning

At present, the chmod task only works in Unix and the NonStop Kernel (Tandem).

Table 4-16. The chmod task’s attributes

Attribute

Description

Required

Default

defaultexcludes

Specifies if you want to use default excludes. Set to yes/no.

No

Default excludes are used.

dir

Specifies the directory holding the files to work on.

One of file, dir, or nested fileset/list elements.

 

excludes

Specifies the patterns matching files to exclude, as a comma- or space-separated list.

No

 

file

Specifies the file or single directory where you want permissions to be changed.

One of file, dir, or nested fileset/list elements.

 

includes

Specifies the patterns matching files to include, as a comma- or space-separated list.

No

 

maxparallel

Specifies limits on how many files to pass at once. Set this attribute to 0 or negative values for unlimited parallelism. Available in Ant 1.6 or later.

No

unlimited

parallel

Specifies the task should process multiple files using a single chmod command.

No

true

perm

Specifies the new permissions you want.

Yes

 

type

Specifies the target type. Possible values: file, dir, or both.

No

file

verbose

Specifies whether the task should display what it’s doing as it does it. Available in Ant 1.6 or later.

No

false

This task holds an implicit FileSet and supports all of FileSet’s attributes and nested elements directly. Since Ant 1.6, you can specify nested fileset or dirset elements, and you can use nested filelists.

Scheduling Automatic Builds

It’s time to add some automation to the build process. When you’re working alone, you probably won’t need to automate nightly builds, but as part of a team, it’s a good idea. Larger projects typically have nightly builds posted to a web site, and using various automation tools and tasks like ftp, that’s no problem. I’ll take a look at various options here.

Unix

You can schedule recurring builds with Unix utilies like crontab, which you use to configure the cron daemon. For example, say you have a shell script that runs your nightly build, dobuild.sh, something like this:

export ANT_HOME=/usr/local/ant
export JAVA_HOME=/usr/local/jdk1.4
export PATH=${PATH}:${ANT_HOME}/bin
cd /home/work
ant -f nightlybuild.xml

You can schedule that build to happen at various times with crontab by starting its editing mode:

-bash-2.05b$ crontab -e

Edit the crontab file to include this line:

run at 00:01 every day 30 0 * * * $HOME/work/dobuild.sh

That makes your build run every night at 12:01 A.M. Easy enough.

Windows

The Windows at command schedules commands to run in Windows at specific times. For example, say you had a batch file, dobuild.bat, which runs your nightly build:

set ANT_HOME=C:\ant\apache-ant-1.6.1
set JAVA_HOME=C:\jdk1.4 
set PATH=%PATH%;%ANT_HOME%\bin
cd C:\work
call %ANT_HOME%\bin\ant.bat -f nightlybuild.xml

You can schedule that build for every night with the Windows at command:

C:\ant>at 00:01 /every:M,T,W,Th,F "C:\work\dobuild.bat"
Added a new job with job ID = 1

To list scheduled at jobs, enter at:

C:\ant>at
Status ID   Day                     Time          Command Line
-------------------------------------------------------------------------------
        1   Each M T W Th F         12:01 AM      C:\work\dobuild.bat

Tip

Want to get the results of your nightly build emailed to you? Use the Ant mail logger, covered earlier in this chapter.

The crontab and at commands are basic ways to get your builds to run automatically, but they’re still basic. There are more advanced and powerful tools available.

Anthill

In my opinion, Anthill is the easist of the automatic build tools to use as well as the easiest to install. It’s a software build management server that can handle most of your build needs, from individual up to the corporate. The web site is http://www.urbancode.com/default.jsp, and this is how Anthill describes itself:

Anthill ensures a controlled build process and promotes the sharing of knowledge within an organization. Anthill performs a checkout from the source repository of the latest version of a project before every build and tags the repository with a unique build number after every build. It supports many repository adapters including: Concurrent Version System (CVS), Visual Source Safe, Perforce, Clearcase, PVCS, StarTeam, MKSIntegrity and FileSystem. Anthill automatically updates a project intranet site with artifacts from the latest build.

Anthill comes in two versions: Anthill Pro (fairly expensive) and Anthill OS (free). To install Anthill, download the binary distribution you want and expand it. Copy anthill.war from the expanded dist directory to a Web server’s application deployment directory, such as the webapps directory of a Tomcat server installation.

Anthill is designed to be used with a Web server that can execute Java code, like Tomcat, and you can get Tomcat free from http://jakarta.apache.org/tomcat/. (Anthill was developed and has only been tested using the Tomcat server, though it’s supposed to work with any servlet container.)

Anthill gives you a servlet-based console, hosted by Tomcat or similar server, that lets you configure your automatic build process. Anthill is designed to check source code out of a code repository automatically and build that code.

For example, you can test your Anthill installation by logging into the Anthill CVS server to retrieve the code for a project named anthill-test, using the password “anthill-example”:

%cvs -d :pserver:anthill-example@cvs2.urbancode.com:/usr/local/anthill-test login
Logging in to :pserver:anthill-example@cvs2.urbancode.com:2401:/usr/local/anthill-test
CVS password: ***************

In the same command-prompt session, start Tomcat and navigate to http://localhost:8080/anthill to open the Anthill console, as shown in Figure 4-1. This is the console that lets you schedule and configure your builds. Successfully built projects are marked with a green box in the right column of the console.

The Anthill build management server
Figure 4-1. The Anthill build management server

Having logged into the Anthill CVS server, click the Build hyperlink in the top line of the table shown in Figure 4-1, which will build the CVS_Anthill example. This opens the Build Project page shown in Figure 4-2. Click the Force Build checkbox, enter a build version such as 1.1, and click the Build button.

Forcing a build
Figure 4-2. Forcing a build

Anthill will download the code for this project from the Anthill CVS server and build it. The Anthill console page will reappear; click Refresh to verify that the project has been built. A green box should appear at right in the CVS Anthill-Example line in the console table, as shown in Figure 4-3, if the build was successful.

Running a new build
Figure 4-3. Running a new build

If you click the CVS_Anthill-Example hyperlink in the console now, you’ll get access to the results of the build, as shown in Figure 4-4.

Build artifacts
Figure 4-4. Build artifacts

The tests hyperlink links to the results of JUnit tests, and the buildLogs hyperlink links to the build log. Here’s what the build log looks like:

all:

compile:
    [mkdir] Created dir: D:\anthill\work\Anthill-Example\build\temp
    [mkdir] Created dir: D:\anthill\work\Anthill-Example\build\temp\classes
    [javac] Compiling 1 source file to D:\anthill\work\Anthill-Example\build\temp\classes
     [copy] Copying 1 file to D:\anthill\work\Anthill-Example\build\temp\classes

jars:
      [jar] Building jar: D:\anthill\publishDir\CVS_Anthill-Example\Anthill-Example-1.1.jar

compile:

compile-tests:
    [mkdir] Created dir: D:\anthill\work\Anthill-Example\build\temp\tests\classes
    [javac] Compiling 1 source file to D:\anthill\work\Anthill-Example\build\temp\
tests\classes
      [jar] Building jar: D:\anthill\publishDir\CVS_Anthill-Example\
Anthill-Example-tests-1.1.jar

run-tests:
    [mkdir] Created dir: D:\anthill\work\Anthill-Example\build\temp\tests\data
    [mkdir] Created dir: D:\anthill\publishDir\CVS_Anthill-Example\tests
    [junit] Running example.WidgetTestCase
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.651 sec
    [junit] Testsuite: example.WidgetTestCase
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.651 sec

[junitreport] Using Xalan version: Xalan Java 2.2.D11
[junitreport] Transform time: 1051ms

doc:

javadoc:
    [mkdir] Created dir: D:\anthill\publishDir\CVS_Anthill-Example\api
  [javadoc] Generating Javadoc
  [javadoc] Javadoc execution
  [javadoc] Loading source files for package example...
  [javadoc] Constructing Javadoc information...
  [javadoc] Standard Doclet version 1.4.0

  [javadoc] Building tree for all the packages and classes...
  [javadoc] Building index for all the packages and classes...
  [javadoc] D:\anthill\work\Anthill-Example\source\java\example\Widget.java:12: 
warning - @author tag has no arguments.
  [javadoc] Building index for all classes...
  [javadoc] Generating D:\anthill\publishDir\CVS_Anthill-Example\api\stylesheet.css...
  [javadoc] 1 warning
        .
        .
        .
clean:
   [delete] Deleting directory D:\anthill\work\Anthill-Example\build\temp

BUILD SUCCESSFUL
Total time: 15 seconds

You schedule builds from the console page, http://localhost:8080/anthill/, if you’re using Tomcat. Click Create New Schedule in the Schedule box, configure the new schedule as shown in Figure 4-5, and click Update to update the scheduler.

Setting up a schedule
Figure 4-5. Setting up a schedule

All in all, Anthill is a great automated build tooleasy to set up, easy to use.

Cruise Control and Gump

Cruise Control and Gump are two other Ant automated build tools for use with Ant. You can get Cruise Control at http://cruisecontrol.sourceforge.net/. It’s an extensive build management tool, but it takes some effort to install. To configure a build, you work with a modification set. Cruise Control supports an Ant task named modificationset that contains nested tasks you can use to configure your build.

After setting up the build as you want it, you start the Cruise Control runner using .sh and .bat scripts, depending on your operating system, and Cruise Control takes it from there.

An alternative automated build tool is Gump. You can get Gump from the Jakarta CVS repository, using the password anoncvs:

%cvs -d :pserver:anoncvs@cvs.apache.org:home/cvspublic login
Logging in to pserver:anoncvs@cvs.apache.org:home/cvspublic
CVS password: *******

%cvs -d :pserver:anoncvs@cvs.apache.org:home/cvspublic checkuot jakarta-alexandria

You can read all about Gump and how it works at http://gump.apache.org/. Using Gump, project definitions are converted from XML to scripts native to the platform on which you are running. These scripts execute CVS or SVN update commands for every module which contains a project being built, and then builds each of those projects.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required