2001-02-13 12:32:01 +00:00
|
|
|
<html>
|
|
|
|
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Language" content="en-us">
|
2002-02-04 20:57:49 +00:00
|
|
|
<title>Writing Your Own Task</title>
|
2001-02-13 12:32:01 +00:00
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
<h1>Developing with Ant</h1>
|
|
|
|
|
|
|
|
<h2><a name="writingowntask">Writing Your Own Task</a></h2>
|
|
|
|
<p>It is very easy to write your own task:</p>
|
|
|
|
<ol>
|
2002-06-01 12:26:43 +00:00
|
|
|
<li>Create a Java class that extends <code>org.apache.tools.ant.Task</code>
|
|
|
|
or <a href="base_task_classes.html">another class</a> that was desgined to be extended.</li>
|
2002-02-04 20:57:49 +00:00
|
|
|
<li>For each attribute, write a <i>setter</i> method. The setter method must be a
|
2001-02-13 12:32:01 +00:00
|
|
|
<code>public void</code> method that takes a single argument. The
|
|
|
|
name of the method must begin with <code>set</code>, followed by the
|
|
|
|
attribute name, with the first character of the name in uppercase, and the rest in
|
2002-03-27 16:32:49 +00:00
|
|
|
|
2003-10-14 08:29:15 +00:00
|
|
|
lowercase<a href="#footnote-1"><sup>*</sup></a>. That is, to support an attribute named
|
2002-03-27 16:32:49 +00:00
|
|
|
<code>file</code> you create a method <code>setFile</code>.
|
|
|
|
Depending on the type of the argument, Ant will perform some
|
|
|
|
conversions for you, see <a href="#set-magic">below</a>.</li>
|
|
|
|
|
|
|
|
<li>If your task shall contain other tasks as nested elements (like
|
|
|
|
<a href="CoreTasks/parallel.html"><code>parallel</code></a>), your
|
|
|
|
class must implement the interface
|
|
|
|
<code>org.apache.tools.ant.TaskContainer</code>. If you do so, your
|
|
|
|
task can not support any other nested elements. See
|
|
|
|
<a href="#taskcontainer">below</a>.</li>
|
|
|
|
|
|
|
|
<li>If the task should support character data (text nested between the
|
|
|
|
start end end tags), write a <code>public void addText(String)</code>
|
|
|
|
method. Note that Ant does <strong>not</strong> expand properties on
|
|
|
|
the text it passes to the task.</li>
|
|
|
|
|
|
|
|
<li>For each nested element, write a <i>create</i>, <i>add</i> or
|
|
|
|
<i>addConfigured</i> method. A create method must be a
|
|
|
|
<code>public</code> method that takes no arguments and returns an
|
|
|
|
<code>Object</code> type. The name of the create method must begin
|
|
|
|
with <code>create</code>, followed by the element name. An add (or
|
|
|
|
addConfigured) method must be a <code>public void</code> method that
|
|
|
|
takes a single argument of an <code>Object</code> type with a
|
|
|
|
no-argument constructor. The name of the add (addConfigured) method
|
|
|
|
must begin with <code>add</code> (<code>addConfigured</code>),
|
|
|
|
followed by the element name. For a more complete discussion see
|
|
|
|
<a href="#nested-elements">below</a>.</li>
|
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<li>Write a <code>public void execute</code> method, with no arguments, that
|
|
|
|
throws a <code>BuildException</code>. This method implements the task
|
|
|
|
itself.</li>
|
|
|
|
</ol>
|
|
|
|
|
2003-10-14 08:29:15 +00:00
|
|
|
<hr>
|
|
|
|
<p><a name="footnote-1">*</a> Actually the case of the letters after
|
|
|
|
the first one doesn't really matter to Ant, using all lower case is a
|
|
|
|
good convention, though.</p>
|
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<h3>The Life-cycle of a Task</h3>
|
|
|
|
<ol>
|
|
|
|
<li>The task gets instantiated using a no-argument constructor, at parser
|
|
|
|
time. This means even tasks that are never executed get
|
|
|
|
instantiated.</li>
|
|
|
|
|
|
|
|
<li>The task gets references to its project and location inside the
|
|
|
|
buildfile via its inherited <code>project</code> and
|
|
|
|
<code>location</code> variables.</li>
|
|
|
|
|
|
|
|
<li>If the user specified an <code>id</code> attribute to this task,
|
|
|
|
the project
|
|
|
|
registers a reference to this newly created task, at parser
|
|
|
|
time.</li>
|
|
|
|
|
|
|
|
<li>The task gets a reference to the target it belongs to via its
|
|
|
|
inherited <code>target</code> variable.</li>
|
|
|
|
|
|
|
|
<li><code>init()</code> is called at parser time.</li>
|
|
|
|
|
|
|
|
<li>All child elements of the XML element corresponding to this task
|
|
|
|
are created via this task's <code>createXXX()</code> methods or
|
|
|
|
instantiated and added to this task via its <code>addXXX()</code>
|
|
|
|
methods, at parser time.</li>
|
|
|
|
|
|
|
|
<li>All attributes of this task get set via their corresponding
|
|
|
|
<code>setXXX</code> methods, at runtime.</li>
|
|
|
|
|
|
|
|
<li>The content character data sections inside the XML element
|
|
|
|
corresponding to this task is added to the task via its
|
|
|
|
<code>addText</code> method, at runtime.</li>
|
|
|
|
|
|
|
|
<li>All attributes of all child elements get set via their corresponding
|
|
|
|
<code>setXXX</code> methods, at runtime.</li>
|
|
|
|
|
2002-03-27 16:32:49 +00:00
|
|
|
<li><a name="execute"><code>execute()</code></a> is called at runtime. While the above initialization
|
2002-02-04 20:57:49 +00:00
|
|
|
steps only occur once, the execute() method may be
|
|
|
|
called more than once, if the task is invoked more than once. For example,
|
2001-02-13 12:32:01 +00:00
|
|
|
if <code>target1</code> and <code>target2</code> both depend
|
2002-02-04 20:57:49 +00:00
|
|
|
on <code>target3</code>, then running
|
2001-02-13 12:32:01 +00:00
|
|
|
<code>'ant target1 target2'</code> will run all tasks in
|
|
|
|
<code>target3</code> twice.</li>
|
|
|
|
</ol>
|
|
|
|
|
2002-03-27 16:32:49 +00:00
|
|
|
<h3><a name="set-magic">Conversions Ant will perform for attributes</a></h3>
|
|
|
|
|
|
|
|
<p>Ant will always expand properties before it passes the value of an
|
|
|
|
attribute to the corresponding setter method.</p>
|
|
|
|
|
|
|
|
<p>The most common way to write an attribute setter is to use a
|
|
|
|
<code>java.lang.String</code> argument. In this case Ant will pass
|
|
|
|
the literal value (after property expansion) to your task. But there
|
|
|
|
is more! If the argument of you setter method is</p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
|
|
<li><code>boolean</code>, your method will be passed the value
|
|
|
|
<i>true</i> if the value specified in the build file is one of
|
|
|
|
<code>true</code>, <code>yes</code>, or <code>on</code> and
|
|
|
|
<i>false</i> otherwise.</li>
|
|
|
|
|
|
|
|
<li><code>char</code> or <code>java.lang.Character</code>, your
|
|
|
|
method will be passed the first character of the value specified in
|
|
|
|
the build file.</li>
|
|
|
|
|
|
|
|
<li>any other primitive type (<code>int</code>, <code>short</code>
|
|
|
|
and so on), Ant will convert the value of the attribute into this
|
|
|
|
type, thus making sure that you'll never receive input that is not a
|
|
|
|
number for that attribute.</li>
|
|
|
|
|
|
|
|
<li><code>java.io.File</code>, Ant will first determine whether the
|
|
|
|
value given in the build file represents an absolute path name. If
|
|
|
|
not, Ant will interpret the value as a path name relative to the
|
|
|
|
project's basedir.</li>
|
|
|
|
|
|
|
|
<li><code>org.apache.tools.ant.types.Path</code>, Ant will tokenize
|
|
|
|
the value specified in the build file, accepting <code>:</code> and
|
|
|
|
<code>;</code> as path separators. Relative path names will be
|
|
|
|
interpreted as relative to the project's basedir.</li>
|
|
|
|
|
|
|
|
<li><code>java.lang.Class</code>, Ant will interpret the value
|
|
|
|
given in the build file as a Java class name and load the named
|
|
|
|
class from the system class loader.</li>
|
|
|
|
|
|
|
|
<li>any other type that has a constructor with a single
|
|
|
|
<code>String</code> argument, Ant will use this constructor to
|
|
|
|
create a new instance from the value given in the build file.</li>
|
|
|
|
|
|
|
|
<li>A subclass of
|
|
|
|
<code>org.apache.tools.ant.types.EnumeratedAttribute</code>, Ant
|
|
|
|
will invoke this classes <code>setValue</code> method. Use this if
|
|
|
|
your task should support enumerated attributes (attributes with
|
|
|
|
values that must be part of a predefined set of values). See
|
|
|
|
<code>org/apache/tools/ant/taskdefs/FixCRLF.java</code> and the
|
|
|
|
inner <code>AddAsisRemove</code> class used in <code>setCr</code>
|
|
|
|
for an example.</li>
|
|
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>What happens if more than one setter method is present for a given
|
|
|
|
attribute? A method taking a <code>String</code> argument will always
|
|
|
|
lose against the more specific methods. If there are still more
|
|
|
|
setters Ant could chose from, only one of them will be called, but we
|
|
|
|
don't know which, this depends on the implementation of your Java
|
|
|
|
virtual machine.</p>
|
|
|
|
|
|
|
|
<h3><a name="nested-elements">Supporting nested elements</a></h3>
|
|
|
|
|
|
|
|
<p>Let's assume your task shall support nested elements with the name
|
|
|
|
<code>inner</code>. First of all, you need a class that represents
|
|
|
|
this nested element. Often you simply want to use one of Ant's
|
|
|
|
classes like <code>org.apache.tools.ant.types.FileSet</code> to
|
|
|
|
support nested <code>fileset</code> elements.</p>
|
|
|
|
|
|
|
|
<p>Attributes of the nested elements or nested child elements of them
|
|
|
|
will be handled using the same mechanism used for tasks (i.e. setter
|
|
|
|
methods for attributes, addText for nested text and
|
|
|
|
create/add/addConfigured methods for child elements).</p>
|
|
|
|
|
|
|
|
<p>Now you have a class <code>NestedElement</code> that is supposed to
|
|
|
|
be used for your nested <code><inner></code> elements, you have
|
|
|
|
three options:</p>
|
|
|
|
|
|
|
|
<ol>
|
|
|
|
<li><code>public NestedElement createInner()</code></li>
|
|
|
|
<li><code>public void addInner(NestedElement anInner)</code></li>
|
|
|
|
<li><code>public void addConfiguredInner(NestedElement anInner)</code></li>
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
<p>What is the difference?</p>
|
|
|
|
|
|
|
|
<p>Option 1 makes the task create the instance of
|
|
|
|
<code>NestedElement</code>, there are no restrictions on the type.
|
|
|
|
For the options 2 and 3, Ant has to create an instance of
|
|
|
|
<code>NestedInner</code> before it can pass it to the task, this
|
|
|
|
means, <code>NestedInner</code> must have a <code>public</code> no-arg
|
2003-10-08 13:29:55 +00:00
|
|
|
constructor or a <code>public</code> one-arg constructor
|
|
|
|
taking a Project class as a parameter.
|
|
|
|
This is the only difference between options 1 and 2.</p>
|
2002-03-27 16:32:49 +00:00
|
|
|
|
|
|
|
<p>The difference between 2 and 3 is what Ant has done to the object
|
|
|
|
before it passes it to the method. <code>addInner</code> will receive
|
|
|
|
an object directly after the constructor has been called, while
|
2002-03-27 17:50:28 +00:00
|
|
|
<code>addConfiguredInner</code> gets the object <em>after</em> the
|
2002-03-27 16:32:49 +00:00
|
|
|
attributes and nested children for this new object have been
|
|
|
|
handled.</p>
|
|
|
|
|
|
|
|
<p>What happens if you use more than one of the options? Only one of
|
|
|
|
the methods will be called, but we don't know which, this depends on
|
|
|
|
the implementation of your Java virtual machine.</p>
|
|
|
|
|
2003-10-08 13:29:55 +00:00
|
|
|
<h3><a name="nestedtype">Nested Types</a></h3>
|
|
|
|
If your task needs to nest an arbitary type that has been defined
|
|
|
|
using <taskdef> you have two options.
|
|
|
|
<ol>
|
|
|
|
<li><code>public void add(Type type)</code></li>
|
|
|
|
<li><code>public void addConfigured(Type type)</code></li>
|
|
|
|
</ol>
|
|
|
|
The difference between 1 and 2 is the same as between 2 and 3 in the
|
|
|
|
previous section.
|
|
|
|
<p>
|
|
|
|
For example suppose one wanted to handle objects object of type
|
|
|
|
org.apache.tools.ant.taskdefs.condition.Condition, one may
|
|
|
|
have a class:
|
|
|
|
</p>
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
public class MyTask extends Task {
|
|
|
|
private List conditions = new ArrayList();
|
|
|
|
public void add(Condition c) {
|
|
|
|
conditions.add(c);
|
|
|
|
}
|
|
|
|
public void execute() {
|
|
|
|
// iterator over the conditions
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
|
|
One may define and use this class like this:
|
|
|
|
</p>
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
<taskdef name="mytask" classname="MyTask" classpath="classes"/>
|
|
|
|
<typedef name="condition.equals"
|
|
|
|
classname="org.apache.tools.ant.taskdefs.conditions.Equals"/>
|
|
|
|
<mytask>
|
|
|
|
<condition.equals arg1="${debug}" arg2="true"/>
|
|
|
|
</mytask>
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
|
|
A more complicated example follows:
|
|
|
|
</p>
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
public class Sample {
|
|
|
|
public static class MyFileSelector implements FileSelector {
|
|
|
|
public void setAttrA(int a) {}
|
|
|
|
public void setAttrB(int b) {}
|
|
|
|
public void add(Path path) {}
|
|
|
|
public boolean isSelected(File basedir, String filename, File file) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
interface MyInterface {
|
|
|
|
void setVerbose(boolean val);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class BuildPath extends Path {
|
|
|
|
public BuildPath(Project project) {
|
|
|
|
super(project);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void add(MyInterface inter) {}
|
|
|
|
public void setUrl(String url) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class XInterface implements MyInterface {
|
|
|
|
public void setVerbose(boolean x) {}
|
|
|
|
public void setCount(int c) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
|
|
This class defines a number of static classes that implement/extend
|
|
|
|
Path, MyFileSelector and MyInterface. These may be defined and used
|
|
|
|
as follows:
|
|
|
|
</p>
|
|
|
|
<pre>
|
|
|
|
<blockquote>
|
|
|
|
<typedef name="myfileselector" classname="Sample$MyFileSelector"
|
|
|
|
classpath="classes" loaderref="classes"/>
|
|
|
|
<typedef name="buildpath" classname="Sample$BuildPath"
|
|
|
|
classpath="classes" loaderref="classes"/>
|
|
|
|
<typedef name="xinterface" classname="Sample$XInterface"
|
|
|
|
classpath="classes" loaderref="classes"/>
|
|
|
|
|
|
|
|
<copy todir="copy-classes">
|
|
|
|
<fileset dir="classes">
|
|
|
|
<myfileselector attra="10" attrB="-10">
|
|
|
|
<buildpath path="." url="abc">
|
|
|
|
<xinterface count="4"/>
|
|
|
|
</buildpath>
|
|
|
|
</myfileselector>
|
|
|
|
</fileset>
|
|
|
|
</copy>
|
|
|
|
</blockquote>
|
|
|
|
</pre>
|
2002-03-27 16:32:49 +00:00
|
|
|
<h3><a name="taskcontainer">TaskContainer</a></h3>
|
|
|
|
|
|
|
|
<p>The <code>TaskContainer</code> consists of a single method,
|
|
|
|
<code>addTask</code> that basically is the same as an <a
|
|
|
|
href="#nested-elements">add method</a> for nested elements. The task
|
|
|
|
instances will be configured (their attributes and nested elements
|
|
|
|
have been handled) when your task's <code>execute</code> method gets
|
|
|
|
invoked, but not before that.</p>
|
|
|
|
|
|
|
|
<p>When we <a href="#execute">said</a> <code>execute</code> would be
|
|
|
|
called, we lied ;-). In fact, Ant will call the <code>perform</code>
|
|
|
|
method in <code>org.apache.tools.ant.Task</code>, which in turn calls
|
|
|
|
<code>execute</code>. This method makes sure that <a
|
|
|
|
href="#buildevents">Build Events</a> will be triggered. If you
|
|
|
|
execute the task instances nested into your task, you should also
|
|
|
|
invoke <code>perform</code> on these instances instead of
|
|
|
|
<code>execute</code>.</p>
|
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<h3>Example</h3>
|
|
|
|
<p>Let's write our own task, which prints a message on the
|
|
|
|
<code>System.out</code> stream.
|
|
|
|
The
|
|
|
|
task has one attribute, called <code>message</code>.</p>
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
package com.mydomain;
|
|
|
|
|
|
|
|
import org.apache.tools.ant.BuildException;
|
|
|
|
import org.apache.tools.ant.Task;
|
|
|
|
|
|
|
|
public class MyVeryOwnTask extends Task {
|
2002-03-27 16:32:49 +00:00
|
|
|
private String msg;
|
2001-02-13 12:32:01 +00:00
|
|
|
|
2002-03-27 16:32:49 +00:00
|
|
|
// The method executing the task
|
|
|
|
public void execute() throws BuildException {
|
|
|
|
System.out.println(msg);
|
|
|
|
}
|
2001-02-13 12:32:01 +00:00
|
|
|
|
2002-03-27 16:32:49 +00:00
|
|
|
// The setter for the "message" attribute
|
|
|
|
public void setMessage(String msg) {
|
|
|
|
this.msg = msg;
|
|
|
|
}
|
2001-02-13 12:32:01 +00:00
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
<p>It's really this simple ;-)</p>
|
|
|
|
<p>Adding your task to the system is rather simple too:</p>
|
|
|
|
<ol>
|
|
|
|
<li>Make sure the class that implements your task is in the classpath when
|
|
|
|
starting Ant.</li>
|
|
|
|
<li>Add a <code><taskdef></code> element to your project.
|
|
|
|
This actually adds your task to the system.</li>
|
|
|
|
<li>Use your task in the rest of the buildfile.</li>
|
|
|
|
</ol>
|
|
|
|
|
2001-10-14 04:39:49 +00:00
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<h3>Example</h3>
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
<?xml version="1.0"?>
|
|
|
|
|
|
|
|
<project name="OwnTaskExample" default="main" basedir=".">
|
|
|
|
<taskdef name="mytask" classname="com.mydomain.MyVeryOwnTask"/>
|
|
|
|
|
|
|
|
<target name="main">
|
|
|
|
<mytask message="Hello World! MyVeryOwnTask works!"/>
|
|
|
|
</target>
|
|
|
|
</project>
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
2001-10-14 04:39:49 +00:00
|
|
|
<h3>Example 2</h3>
|
2002-02-04 20:57:49 +00:00
|
|
|
To use a task directly from the buildfile which created it, place the
|
|
|
|
<code><taskdef></code> declaration inside a target
|
2001-10-14 04:39:49 +00:00
|
|
|
<i>after the compilation</i>. Use the <code>classpath</code> attribute of
|
|
|
|
<code><taskdef></code> to point to where the code has just been
|
|
|
|
compiled.
|
|
|
|
<blockquote>
|
|
|
|
<pre>
|
|
|
|
<?xml version="1.0"?>
|
|
|
|
|
|
|
|
<project name="OwnTaskExample2" default="main" basedir=".">
|
|
|
|
|
|
|
|
<target name="build" >
|
|
|
|
<mkdir dir="build"/>
|
|
|
|
<javac srcdir="source" destdir="build"/>
|
|
|
|
</target>
|
2002-02-04 20:57:49 +00:00
|
|
|
|
2001-10-14 04:39:49 +00:00
|
|
|
<target name="declare" depends="build">
|
2002-02-04 20:57:49 +00:00
|
|
|
<taskdef name="mytask"
|
2001-10-14 04:39:49 +00:00
|
|
|
classname="com.mydomain.MyVeryOwnTask"
|
|
|
|
classpath="build"/>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="main" depends="declare">
|
|
|
|
<mytask message="Hello World! MyVeryOwnTask works!"/>
|
|
|
|
</target>
|
|
|
|
</project>
|
|
|
|
</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<p>Another way to add a task (more permanently), is to add the task name and
|
|
|
|
implementing class name to the <code>default.properties</code> file in the
|
|
|
|
<code>org.apache.tools.ant.taskdefs</code>
|
|
|
|
package. Then you can use it as if it were a built-in task.</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
<h2><a name="buildevents">Build Events</a></h2>
|
2002-02-04 20:57:49 +00:00
|
|
|
<P>Ant is capable of generating build events as it performs the tasks necessary to build a project.
|
2001-02-13 12:32:01 +00:00
|
|
|
Listeners can be attached to Ant to receive these events. This capability could be used, for example,
|
2002-02-04 20:57:49 +00:00
|
|
|
to connect Ant to a GUI or to integrate Ant with an IDE.
|
2001-02-13 12:32:01 +00:00
|
|
|
</P>
|
2002-02-04 20:57:49 +00:00
|
|
|
<p>To use build events you need to create an ant <code>Project</code> object. You can then call the
|
2001-02-13 12:32:01 +00:00
|
|
|
<code>addBuildListener</code> method to add your listener to the project. Your listener must implement
|
2002-02-04 20:57:49 +00:00
|
|
|
the <code>org.apache.tools.antBuildListener</code> interface. The listener will receive BuildEvents
|
2001-02-13 12:32:01 +00:00
|
|
|
for the following events</P>
|
|
|
|
<ul>
|
|
|
|
<li>Build started</li>
|
|
|
|
<li>Build finished</li>
|
|
|
|
<li>Target started</li>
|
|
|
|
<li>Target finished</li>
|
|
|
|
<li>Task started</li>
|
|
|
|
<li>Task finished</li>
|
|
|
|
<li>Message logged</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
If you wish to attach a listener from the command line you may use the
|
|
|
|
<code>-listener</code> option. For example:</p>
|
|
|
|
<blockquote>
|
|
|
|
<pre>ant -listener org.apache.tools.ant.XmlLogger</pre>
|
|
|
|
</blockquote>
|
2002-02-04 20:57:49 +00:00
|
|
|
<p>will run Ant with a listener that generates an XML representation of the build progress. This
|
2001-02-13 12:32:01 +00:00
|
|
|
listener is included with Ant, as is the default listener, which generates the logging to standard output.</p>
|
|
|
|
|
2003-02-17 14:12:10 +00:00
|
|
|
<p><b>Note: </b>A listener must not access System.out and System.err directly since ouput on
|
|
|
|
these streams is redirected by Ant's core to the build event system. Accessing these
|
|
|
|
streams can cause an infinite loop in Ant. Depending on the version of Ant, this will
|
|
|
|
either cause the build to terminate or the Java VM to run out of Stack space. A logger, also, may
|
|
|
|
not access System.out and System.err directly. It must use the streams with which it has
|
|
|
|
been configured.
|
|
|
|
</p>
|
|
|
|
|
2001-11-09 21:15:10 +00:00
|
|
|
<hr>
|
|
|
|
<h2><a name="integration">Source code integration</a></h2>
|
|
|
|
|
|
|
|
|
2002-02-04 20:57:49 +00:00
|
|
|
The other way to extend Ant through Java is to make changes to existing tasks, which is positively encouraged.
|
|
|
|
Both changes to the existing source and new tasks can be incorporated back into the Ant codebase, which
|
2001-11-09 21:15:10 +00:00
|
|
|
benefits all users and spreads the maintenance load around.
|
|
|
|
<p>
|
|
|
|
|
2002-02-04 20:57:49 +00:00
|
|
|
Please consult the
|
2001-11-09 21:15:10 +00:00
|
|
|
<a href="http://jakarta.apache.org/site/getinvolved.html">Getting Involved</a> pages on the Jakarta web site
|
2002-02-04 20:57:49 +00:00
|
|
|
for details on how to fetch the latest source and how to submit changes for reincorporation into the
|
|
|
|
source tree.
|
2001-11-09 21:15:10 +00:00
|
|
|
<p>
|
|
|
|
Ant also has some
|
2003-01-24 08:55:06 +00:00
|
|
|
<a href="http://ant.apache.org/ant_task_guidelines.html">task guidelines</a>
|
2001-11-09 21:15:10 +00:00
|
|
|
which provides some advice to people developing and testing tasks. Even if you intend to
|
2002-02-04 20:57:49 +00:00
|
|
|
keep your tasks to yourself, you should still read this as it should be informative.
|
2001-11-09 21:15:10 +00:00
|
|
|
|
2001-02-13 12:32:01 +00:00
|
|
|
<hr>
|
2003-01-24 08:55:06 +00:00
|
|
|
<p align="center">Copyright © 2000-2003 Apache Software Foundation. All rights
|
2001-02-13 12:32:01 +00:00
|
|
|
Reserved.</p>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|