By Eric M. Burke, Brian M. Coyner
Price: $34.95 USD
£24.95 GBP
Cover | Table of Contents | Colophon
public class Person {
private String firstName;
public void setFirst(String n) {
this.firstName = n;
}
}
n to firstName:public class Person {
private String firstName;
public void setFirst(String firstName) {
this.firstName = firstName;
}
}
setFirstName( ):public class Person {
private String firstName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
<?xml version="1.0"?>
<project name="Template Buildfile" default="compile" basedir=".">
<property name="dir.src" value="src"/>
<property name="dir.build" value="build"/>
<property name="dir.dist" value="dist"/>
<!-- Creates the output directories -->
<target name="prepare">
<mkdir dir="${dir.build}"/>
<mkdir dir="${dir.dist}"/>
</target>
<target name="clean"
description="Remove all generated files.">
<delete dir="${dir.build}"/>
<delete dir="${dir.dist}"/>
</target>
<target name="compile" depends="prepare"
description="Compile all source code.">
<javac srcdir="${dir.src}" destdir="${dir.build}"/>
</target>
<target name="jar" depends="compile"
description="Generates oreilly.jar in the 'dist' directory.">
<jar jarfile="${dir.dist}/oreilly.jar"
basedir="${dir.build}"/>
</target>
</project>
<project>
tag is
found in all buildfiles:<project name="Template Buildfile" default="compile" basedir=".">
default
attribute
specifies which target is invoked when the user types
ant. Finally, the
basedir
attribute specifies the directory
from which all paths are relative to. Regardless of where you invoke
Ant, "." is the directory
containing the buildfile.ant [options] [target [target2 [target3] ...]]
|
Option
|
Description
|
|---|---|
-buildfile
file
-f
file
-file
file
|
Specify which buildfile to use. If omitted, Ant searches for a file
named build.xml.
|
-D
property
=
value
|
Pass name/value pairs as properties.
|
-debug
|
Write debugging information as the build progresses.
|
-diagnostics
|
Write diagnostic information as the build progresses.
|
|
|
description
attribute on the
<project>
and
<target>
tags. Also
consider writing a help target, and use XML comments throughout the
buildfile.help target is listed as the default target and is
executed when the user types ant at the
command line.<?xml version="1.0"?>
<!-- You can document the buildfile using XML comments -->
<project name="My Big Project" default="help" basedir=".">
<description>Shows how to provide help in an Ant buildfile.</description>
<property name="dir.src" value="src"/>
<target name="help">
<echo message="This buildfile shows how to get help."/>
<echo>(Type 'ant -projecthelp' for more info)</echo>
<echo><![CDATA[
Here is a block of text
that you want to format
in a very specific way!]]></echo>
</target>
<!-- Here is an example of a subtarget -->
<target name="prepare">
<mkdir dir="${dir.build}"/>
<mkdir dir="${dir.dist}"/>
</target>
<!-- Here is an example of a main target -->
<target name="clean"
description="Remove all generated files.">
<delete dir="${dir.build}"/>
<delete dir="${dir.dist}"/>
</target>
<target name="compile" depends="prepare"
description="Compile all source code.">
<javac srcdir="${dir.src}" destdir="${dir.build}"/>
</target>
</project>
help
target uses the
echo task to print some usage information for Ant
beginners. It reminds the user of the -projecthelp
option, and uses an XML CDATA section to format a paragraph of text.
CDATA sections are useful whenever you
want to preserve linefeeds, spaces, and other characters precisely.
CDATA is also useful because it allows you to
print
special XML characters
like "<" without using entities
like "<".<property>
task:
<?xml version="1.0"?> <project name="envSample" default="deploy" basedir="."> <!-- Set up the 'env' prefix for environment variables --> <property environment="env"/> <!-- Abort the build if TOMCAT_HOME is not set --> <target name="checkTomcatHome" unless="env.TOMCAT_HOME"> <fail message="TOMCAT_HOME must be set!"/> </target> <target name="compile"> ... compile the code </target> <!-- Deploy the WAR file to TOMCAT_HOME/webapps --> <target name="deploy" depends="checkTomcatHome,compile"> <echo>Deploying to ${env.TOMCAT_HOME}</echo> <copy file="myapp.war" todir="${env.TOMCAT_HOME}/webapps"/> </target> </project>
System.getEnv( ) method,
which used to return the values of environment variables. Undeterred
by this restriction, Ant's programmers added the
ability to obtain environment variables using the technique shown
here.property task's
environment
attribute to define a prefix,
conventionally "env". Then use this
prefix when referencing environment variables in other parts of a
buildfile, as if you are referencing any normal Ant property. Our
example Ant buildfile uses the
TOMCAT_HOME
environment variable to
deploy a Web Application Archive (WAR) file to the correct directory.TOMCAT_HOME is actually set before attempting to
deploy the
WAR file. This is done in the
checkTomcatHome target:<target name="checkTomcatHome" unless="env.TOMCAT_HOME"> <fail message="TOMCAT_HOME must be set!"/> </target>
ant -Dprop1="My Property" run
${prop1}
syntax. You can specify
default values for properties using the
<property> tag, and you can pass system
properties to Java applications using the
<sysproperty> tag nested within the
<java> element.<?xml version="1.0"?> <project name="sysprops" default="run" basedir="."> <!-- define two properties --> <property name="prop1" value="Property 1 from Buildfile"/> <property name="prop2" value="Property 2 from Buildfile"/> <target name="clean"> <delete dir="com"/> </target> <target name="compile"> <javac srcdir="." destdir="."> <classpath path="."/> </javac> </target> <target name="run" depends="compile"> <!-- echo each of the properties to the console --> <echo message="Now in buildfile..."/> <echo message="prop1 = ${prop1}"/> <echo message="prop2 = ${prop2}"/> <!-- The 'prop3' property must be defined on the command line or it shows up like '${prop3}' --> <echo message="prop3 = ${prop3}"/> <echo message="user.home = ${user.home}"/> <!-- execute the main( ) method in a Java class --> <java classname="com.oreilly.javaxp.ShowProps"> <classpath path="."/> <!-- pass one of the properties --> <sysproperty key="prop1" value="${prop1}"/>
fail task to abort
the
build if any properties are undefined.<target name="checkProperties"> <fail unless="env.TOMCAT_HOME">TOMCAT_HOME must be set</fail> <fail unless="env.JUNIT_HOME">JUNIT_HOME must be set</fail> <fail unless="env.JBOSS_HOME">JBOSS_HOME must be set</fail> </target>
<target name="compile" depends="checkProperties"> ... </target>
checkProperties
target executes before Ant attempts to compile your code.<path>
element to define the classpath
along with a unique ID. Then refer to the classpath using the ID.javac task.<?xml version="1.0" encoding="UTF-8"?>
<project name="Classpath Sample" default="compile" basedir=".">
<!-- get an environment variable -->
<property environment="env"/>
<property name="tomcatHome" value="${env.TOMCAT_HOME}"/>
<!-- define some directories -->
<property name="dir.src" value="src"/>
<property name="dir.build" value="build"/>
<property name="dir.lib" value="lib"/>
<!-- Define a classpath for use throughout the buildfile -->
<path id="project.classpath">
<pathelement location="${dir.src}"/>
<!-- include Tomcat libraries -->
<fileset dir="${tomcatHome}/common/lib">
<include name="*.jar"/>
</fileset>
<!-- include our own libraries -->
<fileset dir="${dir.lib}">
<include name="*.jar"/>
</fileset>
</path>
<target name="clean">
<delete dir="${dir.build}"/>
</target>
<target name="prepare">
<mkdir dir="${dir.build}"/>
</target>
<target name="compile" depends="prepare">
<!-- use <pathconvert> to convert the path into a property -->
<pathconvert targetos="windows" property="windowsPath"
refid="project.classpath"/>
<!-- now echo the path to the console -->
<echo>Windows path = ${windowsPath}</echo>
<!-- Here is how to use the classpath for compiling -->
<javac destdir="${dir.build}">
<src path="${dir.src}"/>
<classpath refid="project.classpath"/>
</javac>
</target>
</project>
pathconvert
task to convert an Ant
path to native format and store it in a property. Here is how you
define a path and then convert it to Unix format:
<path id="path.test">
<!-- find all unit tests under the build directory -->
<fileset dir="${dir.build}">
<include name="**/Test*.class"/>
</fileset>
</path>
<!-- convert the path to UNIX format, storing it in a property -->
<pathconvert targetos="unix" property="unixPath" refid="path.test"/>
pathconvert task.<include>
and
<exclude>
tags, or
includes and excludes
attributes.includes="src/com/oreilly/util/*.java"
includes="src/**/*.java"
includes="Test?.java"
|
Pattern
|
Matches
|
Does not match
|
|---|---|---|
|
*.java
|
Person.java
|
Person.class
|
|
Person*.java
|
Person.java, PersonA.java, PersonBoss.java |
if and unless attributes of the
<target> tag.xalanInstalled property is set:<target name="compile" if="xalanInstalled"> ... </target>
<target name="installXalan" unless="xalanInstalled"> ... </target>
fail task. See the Ant
documentation for the condition task to learn how
to set properties based upon existence of files, classes, or other
resources.CLASSPATH
environment variable, opens the door for different developers to have
different settings.CLASSPATH.clean target is essential because it ensures
everything will be compiled during the next build. Ant relies on file
timestamps to determine when class files are out of date with respect
to source files. Although this catches most dependencies, it does not
handle many semantic dependencies. For example, you might remove a
method from a base class; the base class will recompile, but any
derived classes will not. The compile may succeed (incorrectly) until
you perform a clean build and find the problem.