[14982] | 1 | <html>
|
---|
| 2 |
|
---|
| 3 | <head>
|
---|
| 4 | <meta http-equiv="Content-Language" content="en-us">
|
---|
| 5 | <title>Writing Your Own Task</title>
|
---|
| 6 | <link rel="stylesheet" type="text/css" href="stylesheets/antmanual.css">
|
---|
| 7 | </head>
|
---|
| 8 |
|
---|
| 9 | <body>
|
---|
| 10 | <h1>Developing with Ant</h1>
|
---|
| 11 |
|
---|
| 12 | <h2><a name="writingowntask">Writing Your Own Task</a></h2>
|
---|
| 13 | <p>It is very easy to write your own task:</p>
|
---|
| 14 | <ol>
|
---|
| 15 | <li>Create a Java class that extends <code>org.apache.tools.ant.Task</code>
|
---|
| 16 | or <a href="base_task_classes.html">another class</a> that was desgined to be extended.</li>
|
---|
| 17 | <li>For each attribute, write a <i>setter</i> method. The setter method must be a
|
---|
| 18 | <code>public void</code> method that takes a single argument. The
|
---|
| 19 | name of the method must begin with <code>set</code>, followed by the
|
---|
| 20 | attribute name, with the first character of the name in uppercase, and the rest in
|
---|
| 21 |
|
---|
| 22 | lowercase<a href="#footnote-1"><sup>*</sup></a>. That is, to support an attribute named
|
---|
| 23 | <code>file</code> you create a method <code>setFile</code>.
|
---|
| 24 | Depending on the type of the argument, Ant will perform some
|
---|
| 25 | conversions for you, see <a href="#set-magic">below</a>.</li>
|
---|
| 26 |
|
---|
| 27 | <li>If your task shall contain other tasks as nested elements (like
|
---|
| 28 | <a href="CoreTasks/parallel.html"><code>parallel</code></a>), your
|
---|
| 29 | class must implement the interface
|
---|
| 30 | <code>org.apache.tools.ant.TaskContainer</code>. If you do so, your
|
---|
| 31 | task can not support any other nested elements. See
|
---|
| 32 | <a href="#taskcontainer">below</a>.</li>
|
---|
| 33 |
|
---|
| 34 | <li>If the task should support character data (text nested between the
|
---|
| 35 | start end end tags), write a <code>public void addText(String)</code>
|
---|
| 36 | method. Note that Ant does <strong>not</strong> expand properties on
|
---|
| 37 | the text it passes to the task.</li>
|
---|
| 38 |
|
---|
| 39 | <li>For each nested element, write a <i>create</i>, <i>add</i> or
|
---|
| 40 | <i>addConfigured</i> method. A create method must be a
|
---|
| 41 | <code>public</code> method that takes no arguments and returns an
|
---|
| 42 | <code>Object</code> type. The name of the create method must begin
|
---|
| 43 | with <code>create</code>, followed by the element name. An add (or
|
---|
| 44 | addConfigured) method must be a <code>public void</code> method that
|
---|
| 45 | takes a single argument of an <code>Object</code> type with a
|
---|
| 46 | no-argument constructor. The name of the add (addConfigured) method
|
---|
| 47 | must begin with <code>add</code> (<code>addConfigured</code>),
|
---|
| 48 | followed by the element name. For a more complete discussion see
|
---|
| 49 | <a href="#nested-elements">below</a>.</li>
|
---|
| 50 |
|
---|
| 51 | <li>Write a <code>public void execute</code> method, with no arguments, that
|
---|
| 52 | throws a <code>BuildException</code>. This method implements the task
|
---|
| 53 | itself.</li>
|
---|
| 54 | </ol>
|
---|
| 55 |
|
---|
| 56 | <hr>
|
---|
| 57 | <p><a name="footnote-1">*</a> Actually the case of the letters after
|
---|
| 58 | the first one doesn't really matter to Ant, using all lower case is a
|
---|
| 59 | good convention, though.</p>
|
---|
| 60 |
|
---|
| 61 | <h3>The Life-cycle of a Task</h3>
|
---|
| 62 | <ol>
|
---|
| 63 | <li>The task gets instantiated using a no-argument constructor, at parser
|
---|
| 64 | time. This means even tasks that are never executed get
|
---|
| 65 | instantiated.</li>
|
---|
| 66 |
|
---|
| 67 | <li>The task gets references to its project and location inside the
|
---|
| 68 | buildfile via its inherited <code>project</code> and
|
---|
| 69 | <code>location</code> variables.</li>
|
---|
| 70 |
|
---|
| 71 | <li>If the user specified an <code>id</code> attribute to this task,
|
---|
| 72 | the project
|
---|
| 73 | registers a reference to this newly created task, at parser
|
---|
| 74 | time.</li>
|
---|
| 75 |
|
---|
| 76 | <li>The task gets a reference to the target it belongs to via its
|
---|
| 77 | inherited <code>target</code> variable.</li>
|
---|
| 78 |
|
---|
| 79 | <li><code>init()</code> is called at parser time.</li>
|
---|
| 80 |
|
---|
| 81 | <li>All child elements of the XML element corresponding to this task
|
---|
| 82 | are created via this task's <code>createXXX()</code> methods or
|
---|
| 83 | instantiated and added to this task via its <code>addXXX()</code>
|
---|
| 84 | methods, at parser time.</li>
|
---|
| 85 |
|
---|
| 86 | <li>All attributes of this task get set via their corresponding
|
---|
| 87 | <code>setXXX</code> methods, at runtime.</li>
|
---|
| 88 |
|
---|
| 89 | <li>The content character data sections inside the XML element
|
---|
| 90 | corresponding to this task is added to the task via its
|
---|
| 91 | <code>addText</code> method, at runtime.</li>
|
---|
| 92 |
|
---|
| 93 | <li>All attributes of all child elements get set via their corresponding
|
---|
| 94 | <code>setXXX</code> methods, at runtime.</li>
|
---|
| 95 |
|
---|
| 96 | <li><a name="execute"><code>execute()</code></a> is called at runtime. While the above initialization
|
---|
| 97 | steps only occur once, the execute() method may be
|
---|
| 98 | called more than once, if the task is invoked more than once. For example,
|
---|
| 99 | if <code>target1</code> and <code>target2</code> both depend
|
---|
| 100 | on <code>target3</code>, then running
|
---|
| 101 | <code>'ant target1 target2'</code> will run all tasks in
|
---|
| 102 | <code>target3</code> twice.</li>
|
---|
| 103 | </ol>
|
---|
| 104 |
|
---|
| 105 | <a name="set-magic"></a><h3>Conversions Ant will perform for attributes</h3>
|
---|
| 106 |
|
---|
| 107 | <p>Ant will always expand properties before it passes the value of an
|
---|
| 108 | attribute to the corresponding setter method.</p>
|
---|
| 109 |
|
---|
| 110 | <p>The most common way to write an attribute setter is to use a
|
---|
| 111 | <code>java.lang.String</code> argument. In this case Ant will pass
|
---|
| 112 | the literal value (after property expansion) to your task. But there
|
---|
| 113 | is more! If the argument of you setter method is</p>
|
---|
| 114 |
|
---|
| 115 | <ul>
|
---|
| 116 |
|
---|
| 117 | <li><code>boolean</code>, your method will be passed the value
|
---|
| 118 | <i>true</i> if the value specified in the build file is one of
|
---|
| 119 | <code>true</code>, <code>yes</code>, or <code>on</code> and
|
---|
| 120 | <i>false</i> otherwise.</li>
|
---|
| 121 |
|
---|
| 122 | <li><code>char</code> or <code>java.lang.Character</code>, your
|
---|
| 123 | method will be passed the first character of the value specified in
|
---|
| 124 | the build file.</li>
|
---|
| 125 |
|
---|
| 126 | <li>any other primitive type (<code>int</code>, <code>short</code>
|
---|
| 127 | and so on), Ant will convert the value of the attribute into this
|
---|
| 128 | type, thus making sure that you'll never receive input that is not a
|
---|
| 129 | number for that attribute.</li>
|
---|
| 130 |
|
---|
| 131 | <li><code>java.io.File</code>, Ant will first determine whether the
|
---|
| 132 | value given in the build file represents an absolute path name. If
|
---|
| 133 | not, Ant will interpret the value as a path name relative to the
|
---|
| 134 | project's basedir.</li>
|
---|
| 135 |
|
---|
| 136 | <li><code>org.apache.tools.ant.types.Path</code>, Ant will tokenize
|
---|
| 137 | the value specified in the build file, accepting <code>:</code> and
|
---|
| 138 | <code>;</code> as path separators. Relative path names will be
|
---|
| 139 | interpreted as relative to the project's basedir.</li>
|
---|
| 140 |
|
---|
| 141 | <li><code>java.lang.Class</code>, Ant will interpret the value
|
---|
| 142 | given in the build file as a Java class name and load the named
|
---|
| 143 | class from the system class loader.</li>
|
---|
| 144 |
|
---|
| 145 | <li>any other type that has a constructor with a single
|
---|
| 146 | <code>String</code> argument, Ant will use this constructor to
|
---|
| 147 | create a new instance from the value given in the build file.</li>
|
---|
| 148 |
|
---|
| 149 | <li>A subclass of
|
---|
| 150 | <code>org.apache.tools.ant.types.EnumeratedAttribute</code>, Ant
|
---|
| 151 | will invoke this classes <code>setValue</code> method. Use this if
|
---|
| 152 | your task should support enumerated attributes (attributes with
|
---|
| 153 | values that must be part of a predefined set of values). See
|
---|
| 154 | <code>org/apache/tools/ant/taskdefs/FixCRLF.java</code> and the
|
---|
| 155 | inner <code>AddAsisRemove</code> class used in <code>setCr</code>
|
---|
| 156 | for an example.</li>
|
---|
| 157 |
|
---|
| 158 | </ul>
|
---|
| 159 |
|
---|
| 160 | <p>What happens if more than one setter method is present for a given
|
---|
| 161 | attribute? A method taking a <code>String</code> argument will always
|
---|
| 162 | lose against the more specific methods. If there are still more
|
---|
| 163 | setters Ant could chose from, only one of them will be called, but we
|
---|
| 164 | don't know which, this depends on the implementation of your Java
|
---|
| 165 | virtual machine.</p>
|
---|
| 166 |
|
---|
| 167 | <a name="nested-elements"></a><h3>Supporting nested elements</h3>
|
---|
| 168 |
|
---|
| 169 | <p>Let's assume your task shall support nested elements with the name
|
---|
| 170 | <code>inner</code>. First of all, you need a class that represents
|
---|
| 171 | this nested element. Often you simply want to use one of Ant's
|
---|
| 172 | classes like <code>org.apache.tools.ant.types.FileSet</code> to
|
---|
| 173 | support nested <code>fileset</code> elements.</p>
|
---|
| 174 |
|
---|
| 175 | <p>Attributes of the nested elements or nested child elements of them
|
---|
| 176 | will be handled using the same mechanism used for tasks (i.e. setter
|
---|
| 177 | methods for attributes, addText for nested text and
|
---|
| 178 | create/add/addConfigured methods for child elements).</p>
|
---|
| 179 |
|
---|
| 180 | <p>Now you have a class <code>NestedElement</code> that is supposed to
|
---|
| 181 | be used for your nested <code><inner></code> elements, you have
|
---|
| 182 | three options:</p>
|
---|
| 183 |
|
---|
| 184 | <ol>
|
---|
| 185 | <li><code>public NestedElement createInner()</code></li>
|
---|
| 186 | <li><code>public void addInner(NestedElement anInner)</code></li>
|
---|
| 187 | <li><code>public void addConfiguredInner(NestedElement anInner)</code></li>
|
---|
| 188 | </ol>
|
---|
| 189 |
|
---|
| 190 | <p>What is the difference?</p>
|
---|
| 191 |
|
---|
| 192 | <p>Option 1 makes the task create the instance of
|
---|
| 193 | <code>NestedElement</code>, there are no restrictions on the type.
|
---|
| 194 | For the options 2 and 3, Ant has to create an instance of
|
---|
| 195 | <code>NestedInner</code> before it can pass it to the task, this
|
---|
| 196 | means, <code>NestedInner</code> must have a <code>public</code> no-arg
|
---|
| 197 | constructor or a <code>public</code> one-arg constructor
|
---|
| 198 | taking a Project class as a parameter.
|
---|
| 199 | This is the only difference between options 1 and 2.</p>
|
---|
| 200 |
|
---|
| 201 | <p>The difference between 2 and 3 is what Ant has done to the object
|
---|
| 202 | before it passes it to the method. <code>addInner</code> will receive
|
---|
| 203 | an object directly after the constructor has been called, while
|
---|
| 204 | <code>addConfiguredInner</code> gets the object <em>after</em> the
|
---|
| 205 | attributes and nested children for this new object have been
|
---|
| 206 | handled.</p>
|
---|
| 207 |
|
---|
| 208 | <p>What happens if you use more than one of the options? Only one of
|
---|
| 209 | the methods will be called, but we don't know which, this depends on
|
---|
| 210 | the implementation of your Java virtual machine.</p>
|
---|
| 211 |
|
---|
| 212 | <a name="nestedtype"></a><h3>Nested Types</h3>
|
---|
| 213 | If your task needs to nest an arbitary type that has been defined
|
---|
| 214 | using <typedef> you have two options.
|
---|
| 215 | <ol>
|
---|
| 216 | <li><code>public void add(Type type)</code></li>
|
---|
| 217 | <li><code>public void addConfigured(Type type)</code></li>
|
---|
| 218 | </ol>
|
---|
| 219 | The difference between 1 and 2 is the same as between 2 and 3 in the
|
---|
| 220 | previous section.
|
---|
| 221 | <p>
|
---|
| 222 | For example suppose one wanted to handle objects object of type
|
---|
| 223 | org.apache.tools.ant.taskdefs.condition.Condition, one may
|
---|
| 224 | have a class:
|
---|
| 225 | </p>
|
---|
| 226 | <blockquote>
|
---|
| 227 | <pre>
|
---|
| 228 | public class MyTask extends Task {
|
---|
| 229 | private List conditions = new ArrayList();
|
---|
| 230 | public void add(Condition c) {
|
---|
| 231 | conditions.add(c);
|
---|
| 232 | }
|
---|
| 233 | public void execute() {
|
---|
| 234 | // iterator over the conditions
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 | </pre>
|
---|
| 238 | </blockquote>
|
---|
| 239 | <p>
|
---|
| 240 | One may define and use this class like this:
|
---|
| 241 | </p>
|
---|
| 242 | <blockquote>
|
---|
| 243 | <pre>
|
---|
| 244 | <taskdef name="mytask" classname="MyTask" classpath="classes"/>
|
---|
| 245 | <typedef name="condition.equals"
|
---|
| 246 | classname="org.apache.tools.ant.taskdefs.conditions.Equals"/>
|
---|
| 247 | <mytask>
|
---|
| 248 | <condition.equals arg1="${debug}" arg2="true"/>
|
---|
| 249 | </mytask>
|
---|
| 250 | </pre>
|
---|
| 251 | </blockquote>
|
---|
| 252 | <p>
|
---|
| 253 | A more complicated example follows:
|
---|
| 254 | </p>
|
---|
| 255 | <blockquote>
|
---|
| 256 | <pre>
|
---|
| 257 | public class Sample {
|
---|
| 258 | public static class MyFileSelector implements FileSelector {
|
---|
| 259 | public void setAttrA(int a) {}
|
---|
| 260 | public void setAttrB(int b) {}
|
---|
| 261 | public void add(Path path) {}
|
---|
| 262 | public boolean isSelected(File basedir, String filename, File file) {
|
---|
| 263 | return true;
|
---|
| 264 | }
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | interface MyInterface {
|
---|
| 268 | void setVerbose(boolean val);
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | public static class BuildPath extends Path {
|
---|
| 272 | public BuildPath(Project project) {
|
---|
| 273 | super(project);
|
---|
| 274 | }
|
---|
| 275 |
|
---|
| 276 | public void add(MyInterface inter) {}
|
---|
| 277 | public void setUrl(String url) {}
|
---|
| 278 | }
|
---|
| 279 |
|
---|
| 280 | public static class XInterface implements MyInterface {
|
---|
| 281 | public void setVerbose(boolean x) {}
|
---|
| 282 | public void setCount(int c) {}
|
---|
| 283 | }
|
---|
| 284 | }
|
---|
| 285 | </pre>
|
---|
| 286 | </blockquote>
|
---|
| 287 | <p>
|
---|
| 288 | This class defines a number of static classes that implement/extend
|
---|
| 289 | Path, MyFileSelector and MyInterface. These may be defined and used
|
---|
| 290 | as follows:
|
---|
| 291 | </p>
|
---|
| 292 | <pre>
|
---|
| 293 | <blockquote>
|
---|
| 294 | <typedef name="myfileselector" classname="Sample$MyFileSelector"
|
---|
| 295 | classpath="classes" loaderref="classes"/>
|
---|
| 296 | <typedef name="buildpath" classname="Sample$BuildPath"
|
---|
| 297 | classpath="classes" loaderref="classes"/>
|
---|
| 298 | <typedef name="xinterface" classname="Sample$XInterface"
|
---|
| 299 | classpath="classes" loaderref="classes"/>
|
---|
| 300 |
|
---|
| 301 | <copy todir="copy-classes">
|
---|
| 302 | <fileset dir="classes">
|
---|
| 303 | <myfileselector attra="10" attrB="-10">
|
---|
| 304 | <buildpath path="." url="abc">
|
---|
| 305 | <xinterface count="4"/>
|
---|
| 306 | </buildpath>
|
---|
| 307 | </myfileselector>
|
---|
| 308 | </fileset>
|
---|
| 309 | </copy>
|
---|
| 310 | </blockquote>
|
---|
| 311 | </pre>
|
---|
| 312 | <a name="taskcontainer"></a><h3>TaskContainer</h3>
|
---|
| 313 |
|
---|
| 314 | <p>The <code>TaskContainer</code> consists of a single method,
|
---|
| 315 | <code>addTask</code> that basically is the same as an <a
|
---|
| 316 | href="#nested-elements">add method</a> for nested elements. The task
|
---|
| 317 | instances will be configured (their attributes and nested elements
|
---|
| 318 | have been handled) when your task's <code>execute</code> method gets
|
---|
| 319 | invoked, but not before that.</p>
|
---|
| 320 |
|
---|
| 321 | <p>When we <a href="#execute">said</a> <code>execute</code> would be
|
---|
| 322 | called, we lied ;-). In fact, Ant will call the <code>perform</code>
|
---|
| 323 | method in <code>org.apache.tools.ant.Task</code>, which in turn calls
|
---|
| 324 | <code>execute</code>. This method makes sure that <a
|
---|
| 325 | href="#buildevents">Build Events</a> will be triggered. If you
|
---|
| 326 | execute the task instances nested into your task, you should also
|
---|
| 327 | invoke <code>perform</code> on these instances instead of
|
---|
| 328 | <code>execute</code>.</p>
|
---|
| 329 |
|
---|
| 330 | <h3>Example</h3>
|
---|
| 331 | <p>Let's write our own task, which prints a message on the
|
---|
| 332 | <code>System.out</code> stream.
|
---|
| 333 | The
|
---|
| 334 | task has one attribute, called <code>message</code>.</p>
|
---|
| 335 | <blockquote>
|
---|
| 336 | <pre>
|
---|
| 337 | package com.mydomain;
|
---|
| 338 |
|
---|
| 339 | import org.apache.tools.ant.BuildException;
|
---|
| 340 | import org.apache.tools.ant.Task;
|
---|
| 341 |
|
---|
| 342 | public class MyVeryOwnTask extends Task {
|
---|
| 343 | private String msg;
|
---|
| 344 |
|
---|
| 345 | // The method executing the task
|
---|
| 346 | public void execute() throws BuildException {
|
---|
| 347 | System.out.println(msg);
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 | // The setter for the "message" attribute
|
---|
| 351 | public void setMessage(String msg) {
|
---|
| 352 | this.msg = msg;
|
---|
| 353 | }
|
---|
| 354 | }
|
---|
| 355 | </pre>
|
---|
| 356 | </blockquote>
|
---|
| 357 | <p>It's really this simple ;-)</p>
|
---|
| 358 | <p>Adding your task to the system is rather simple too:</p>
|
---|
| 359 | <ol>
|
---|
| 360 | <li>Make sure the class that implements your task is in the classpath when
|
---|
| 361 | starting Ant.</li>
|
---|
| 362 | <li>Add a <code><taskdef></code> element to your project.
|
---|
| 363 | This actually adds your task to the system.</li>
|
---|
| 364 | <li>Use your task in the rest of the buildfile.</li>
|
---|
| 365 | </ol>
|
---|
| 366 |
|
---|
| 367 |
|
---|
| 368 | <h3>Example</h3>
|
---|
| 369 | <blockquote>
|
---|
| 370 | <pre>
|
---|
| 371 | <?xml version="1.0"?>
|
---|
| 372 |
|
---|
| 373 | <project name="OwnTaskExample" default="main" basedir=".">
|
---|
| 374 | <taskdef name="mytask" classname="com.mydomain.MyVeryOwnTask"/>
|
---|
| 375 |
|
---|
| 376 | <target name="main">
|
---|
| 377 | <mytask message="Hello World! MyVeryOwnTask works!"/>
|
---|
| 378 | </target>
|
---|
| 379 | </project>
|
---|
| 380 | </pre>
|
---|
| 381 | </blockquote>
|
---|
| 382 | <h3>Example 2</h3>
|
---|
| 383 | To use a task directly from the buildfile which created it, place the
|
---|
| 384 | <code><taskdef></code> declaration inside a target
|
---|
| 385 | <i>after the compilation</i>. Use the <code>classpath</code> attribute of
|
---|
| 386 | <code><taskdef></code> to point to where the code has just been
|
---|
| 387 | compiled.
|
---|
| 388 | <blockquote>
|
---|
| 389 | <pre>
|
---|
| 390 | <?xml version="1.0"?>
|
---|
| 391 |
|
---|
| 392 | <project name="OwnTaskExample2" default="main" basedir=".">
|
---|
| 393 |
|
---|
| 394 | <target name="build" >
|
---|
| 395 | <mkdir dir="build"/>
|
---|
| 396 | <javac srcdir="source" destdir="build"/>
|
---|
| 397 | </target>
|
---|
| 398 |
|
---|
| 399 | <target name="declare" depends="build">
|
---|
| 400 | <taskdef name="mytask"
|
---|
| 401 | classname="com.mydomain.MyVeryOwnTask"
|
---|
| 402 | classpath="build"/>
|
---|
| 403 | </target>
|
---|
| 404 |
|
---|
| 405 | <target name="main" depends="declare">
|
---|
| 406 | <mytask message="Hello World! MyVeryOwnTask works!"/>
|
---|
| 407 | </target>
|
---|
| 408 | </project>
|
---|
| 409 | </pre>
|
---|
| 410 | </blockquote>
|
---|
| 411 |
|
---|
| 412 |
|
---|
| 413 | <p>Another way to add a task (more permanently), is to add the task name and
|
---|
| 414 | implementing class name to the <code>default.properties</code> file in the
|
---|
| 415 | <code>org.apache.tools.ant.taskdefs</code>
|
---|
| 416 | package. Then you can use it as if it were a built-in task.</p>
|
---|
| 417 |
|
---|
| 418 | <hr>
|
---|
| 419 | <a name="buildevents"></a><h2>Build Events</h2>
|
---|
| 420 | <P>Ant is capable of generating build events as it performs the tasks necessary to build a project.
|
---|
| 421 | Listeners can be attached to Ant to receive these events. This capability could be used, for example,
|
---|
| 422 | to connect Ant to a GUI or to integrate Ant with an IDE.
|
---|
| 423 | </P>
|
---|
| 424 | <p>To use build events you need to create an ant <code>Project</code> object. You can then call the
|
---|
| 425 | <code>addBuildListener</code> method to add your listener to the project. Your listener must implement
|
---|
| 426 | the <code>org.apache.tools.antBuildListener</code> interface. The listener will receive BuildEvents
|
---|
| 427 | for the following events</P>
|
---|
| 428 | <ul>
|
---|
| 429 | <li>Build started</li>
|
---|
| 430 | <li>Build finished</li>
|
---|
| 431 | <li>Target started</li>
|
---|
| 432 | <li>Target finished</li>
|
---|
| 433 | <li>Task started</li>
|
---|
| 434 | <li>Task finished</li>
|
---|
| 435 | <li>Message logged</li>
|
---|
| 436 | </ul>
|
---|
| 437 |
|
---|
| 438 | <p>If the build file invokes another build file via <a
|
---|
| 439 | href="CoreTasks/ant.html"><ant></a> or <a
|
---|
| 440 | href="CoreTasks/subant.html"><subant></a> or uses <a
|
---|
| 441 | href="CoreTasks/antcall.html"><antcall></a>, you are creating a
|
---|
| 442 | new Ant "project" that will send target and task level events of its
|
---|
| 443 | own but never sends build started/finished events. Ant 1.6.2
|
---|
| 444 | introduces an extension of the BuildListener interface named
|
---|
| 445 | SubBuildListener that will receive two new events for</p>
|
---|
| 446 | <ul>
|
---|
| 447 | <li>SubBuild started</li>
|
---|
| 448 | <li>SubBuild finished</li>
|
---|
| 449 | </ul>
|
---|
| 450 | <p>If you are interested in those events, all you need to do is to
|
---|
| 451 | implement the new interface instead of BuildListener (and register the
|
---|
| 452 | listener, of course).</p>
|
---|
| 453 |
|
---|
| 454 | <p>
|
---|
| 455 | If you wish to attach a listener from the command line you may use the
|
---|
| 456 | <code>-listener</code> option. For example:</p>
|
---|
| 457 | <blockquote>
|
---|
| 458 | <pre>ant -listener org.apache.tools.ant.XmlLogger</pre>
|
---|
| 459 | </blockquote>
|
---|
| 460 | <p>will run Ant with a listener that generates an XML representation of the build progress. This
|
---|
| 461 | listener is included with Ant, as is the default listener, which generates the logging to standard output.</p>
|
---|
| 462 |
|
---|
| 463 | <p><b>Note: </b>A listener must not access System.out and System.err directly since ouput on
|
---|
| 464 | these streams is redirected by Ant's core to the build event system. Accessing these
|
---|
| 465 | streams can cause an infinite loop in Ant. Depending on the version of Ant, this will
|
---|
| 466 | either cause the build to terminate or the Java VM to run out of Stack space. A logger, also, may
|
---|
| 467 | not access System.out and System.err directly. It must use the streams with which it has
|
---|
| 468 | been configured.
|
---|
| 469 | </p>
|
---|
| 470 |
|
---|
| 471 | <hr>
|
---|
| 472 | <a name="integration"></a><h2>Source code integration</h2>
|
---|
| 473 |
|
---|
| 474 |
|
---|
| 475 | The other way to extend Ant through Java is to make changes to existing tasks, which is positively encouraged.
|
---|
| 476 | Both changes to the existing source and new tasks can be incorporated back into the Ant codebase, which
|
---|
| 477 | benefits all users and spreads the maintenance load around.
|
---|
| 478 | <p>
|
---|
| 479 |
|
---|
| 480 | Please consult the
|
---|
| 481 | <a href="http://jakarta.apache.org/site/getinvolved.html">Getting Involved</a> pages on the Jakarta web site
|
---|
| 482 | for details on how to fetch the latest source and how to submit changes for reincorporation into the
|
---|
| 483 | source tree.
|
---|
| 484 | <p>
|
---|
| 485 | Ant also has some
|
---|
| 486 | <a href="http://ant.apache.org/ant_task_guidelines.html">task guidelines</a>
|
---|
| 487 | which provides some advice to people developing and testing tasks. Even if you intend to
|
---|
| 488 | keep your tasks to yourself, you should still read this as it should be informative.
|
---|
| 489 |
|
---|
| 490 | <hr>
|
---|
| 491 | <p align="center">Copyright © 2000-2004 The Apache Software Foundation. All rights
|
---|
| 492 | Reserved.</p>
|
---|
| 493 |
|
---|
| 494 | </body>
|
---|
| 495 | </html>
|
---|
| 496 |
|
---|