ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Installing Software with Jakarta Ant

by Eric M. Burke
06/05/2002

I develop and teach Java courses, some of which require specific versions of tools like Ant, Xalan, and Tomcat. I normally provide the lab administrators with a readme file explaining how to install each tool, but this approach sometimes fails. For example, I may decide to use a newer version of Tomcat at the last minute, or the person installing the software may install the wrong version of a critical tool.

I was looking for a way to simplify the installation process when a colleague, Mark Volkmann, told me how he uses Ant to install software before each offering of his XML courses. This seemed like a good idea -- and a fun way to introduce Ant to my students. Instead of relying on someone else to install five or six open source tools, I could give the students a simple script, along with a few ZIP files. The script would "bootstrap" a version of Ant, and then use Ant to unzip the remaining tools to a specific directory.

This article describes my modified versions of Mark's software installation script and Ant build file. Hopefully this will inspire you to use Ant for other creative tasks.

Setup

This installation utility has the following requirements:

  • The student PCs must be running Windows NT or later. It would be easy enough to make a Unix installation script, but the lab PCs all run Windows. The platform dependency is a limitation of the initial batch file, rather than the Ant build file.
  • The J2SE SDK must be installed on each student PC. This is because the initial batch file uses the jar utility to bootstrap the Ant distribution.
  • The instructor must have the ability to share a network drive, so that the students can copy the files onto their hard drives.

Figure 1 shows the directory structure for all of the files given to the students. On the first night of class, the students copy this directory structure onto their own PCs so that they can install the software.

Diagram.
Figure 1. Directory structure

Bootstrapping Ant

The root directory, AdvServletJSP, contains a Windows batch file for the students to run. This file creates the tools directory and then uses the jar command to unzip the Ant distribution into the jakarta-ant-1.4.1 directory. Next, the batch file invokes Ant using studentInstall.xml as the build file. Here is the batch file in its entirety:

Example 1. studentInstall.bat

@echo off
setlocal

:: Students run this batch file. It installs Ant, and then 
:: uses Ant to install the remaining packages.

:: Set some variables specific to this version of Ant
set ANT_ZIP=jakarta-ant-1.4.1-bin.zip
set ANT_OPT=jakarta-ant-1.4.1-optional.jar
set ANT_HOME=tools\jakarta-ant-1.4.1

if not exist tools mkdir tools

@echo Unzipping Ant distribution...
cd tools
jar -xf ../downloads/%ANT_ZIP%
cd ..

@echo Copying Ant's optional tasks JAR file...
copy downloads\%ANT_OPT% %ANT_HOME%\lib

@echo Using Ant to install remaining packages...
set PATH=%ANT_HOME%\bin;%PATH%
ant -buildfile studentInstall.xml

endlocal

This batch file should be fairly self-explanatory. It uses Java's jar command to unzip the Ant distribution. This works because .jar files use the same format as .zip files. Once the Ant .zip file is expanded, the batch file copies jakarta-ant-1.4.1-optional.jar into Ant's lib directory.

jakarta-ant-1.4.1-optional.jar contains class files for "optional" Ant tasks. There are several reasons why a task may be considered optional, as opposed to core. For example, many optional tasks require third-party .jar files that Apache cannot distribute because of licensing restrictions. Other optional tasks may handle obscure functionality that does not belong in the core of Ant. At any rate, you will usually want the optional tasks because they include such useful tasks as ftp, junit, and various EJB-related tasks.

The Ant Buildfile

After installing the optional task .jar file, the batch file invokes the ant command, using studentInstall.xml as the build file. Ant takes care of the remainder of the installation, based on the instructions in the build file. Example 2 shows the complete Ant build file.

Example 2. studentInstall.xml

<?xml version="1.0"?>
<project name="Software Installer" default="installAll" basedir=".">
  <!-- destination directories -->
  <property name="destdir" value="tools"/>
  <property name="destdir.tomcat" value="${destdir}/jakarta-tomcat-4.0.3"/>
  <property name="destdir.xalan" value="${destdir}/xalan-j_2_3_1"/>
  <property name="dir.downloads" value="downloads"/>
  <property name="zip.tomcat" value="${dir.downloads}/jakarta-tomcat-4.0.3.zip"/>
  <property name="zip.xalan" value="${dir.downloads}/xalan-j_2_3_1-bin.zip"/>

  <target name="init">
    <available property="haveTomcat" type="dir" file="${destdir.tomcat}"/>
    <available property="haveXalan" type="dir" file="${destdir.xalan}"/>
  </target>

  <target name="prepare" depends="init">
    <mkdir dir="${destdir}"/>
  </target>

  <target name="installTomcat" depends="prepare" unless="haveTomcat">
    <unzip src="${zip.tomcat}" dest="${destdir}"/>
  </target>

  <target name="installXalan" depends="prepare" unless="haveXalan">
    <unzip src="${zip.xalan}" dest="${destdir}"/>
  </target>

  <target name="installAll" depends="installTomcat,installXalan" 
             description="Installs all software">
    <pathconvert targetos="windows" property="tomcat_home">
      <path location="${destdir.tomcat}"/>
    </pathconvert>
    <pathconvert targetos="windows" property="xalan_home">
      <path location="${destdir.xalan}"/>
    </pathconvert>
    <pathconvert targetos="windows" property="ant_home">
      <path location="${ant.home}"/>
    </pathconvert>
    <echo>
      Unless you saw error messages, everything is now installed.
      You should set the following environment variables:
       TOMCAT_HOME=${tomcat_home}
       XALAN_HOME=${xalan_home}
       ANT_HOME=${ant_home}
    </echo>
  </target>

  <target name="uninstall"
    description="Removes all files created by this buildfile">
    <delete dir="${destdir}"/>
  </target>
</project>

The Ant Project

Ant build files must be well-formed XML documents, and ours is no exception. Each build file must have a <project> roo element, which defines the project name, default target, and base directory. The project name is used for documentation purposes, so you will generally want something descriptive. The basedir attribute specifies the location from which paths in the build file are computed.

Ant projects contain one or more targets, which in turn contain one or more tasks. This tree structure is fundamental to Ant, and we'll discuss targets and tasks shortly. But first, let's talk about Ant properties.

Properties

studentInstall.xml defines numerous properties. Using properties keeps all of the hard-coded filenames and version numbers in a single place, which is useful because the names will inevitably change as new tools become available. The properties are declared using the <property> tag, which accepts a name/value pair of strings:

<property name="destdir" value="tools"/>
  <property name="destdir.tomcat" value="${destdir}/jakarta-tomcat-4.0.3"/>
  <property name="destdir.xalan" value="${destdir}/xalan-j_2_3_1"/>
  <property name="dir.downloads" value="downloads"/>
  <property name="zip.tomcat" value="${dir.downloads}/jakarta-tomcat-4.0.3.zip"/>
  <property name="zip.xalan" value="${dir.downloads}/xalan-j_2_3_1-bin.zip"/>

These properties are globally scoped, so they are visible within all of the Ant targets and tasks. You refer to properties using the ${prop_name} syntax, as you can see when we refer to {$destdir}. Properties are constants that cannot be changed once they are declared. This may change in Ant 2.0, but for now, you have to accept that properties are immutable.

All of our properties are defined as target-level elements, so they will be defined before any of the build targets are executed. You can also declare properties inside of targets. In that case, the properties are not defined until the target is executed. Once the properties are defined, however, they are globally scoped, even though they were defined inside of a target.

Pages: 1, 2

Next Pagearrow