source: other-projects/trunk/realistic-books/packages/AntInstaller/web/manual1.6.2/ant_task_guidelines.html@ 19253

Last change on this file since 19253 was 19253, checked in by davidb, 15 years ago

Establishing a source code repository for Veronica's Realistic Book's software

File size: 18.2 KB
Line 
1<html><head>
2<title>
3Apache Ant Task Design Guidelines
4</title>
5<link rel="stylesheet" type="text/css" href="manual/stylesheets/antmanual.css">
6</head><body>
7
8<h1>Apache Ant Task Design Guidelines</h1>
9
10This document covers how to write ant tasks to a standard required to be
11incorporated into the Ant distribution. You may find it useful when
12writing tasks for personal use as the issues it addresses are still
13there in such a case.
14
15
16<h2>Don't break existing builds</h2>
17
18Even if you find some really hideous problem with ant, one that is easy
19to fix, if your fix breaks an existing build file then we have problems.
20Making sure that every build file out there still works, is one of the
21goals of all changes. As an example of this, Ant1.5 passes the single
22dollar sign "$" through in strings; Ant1.4 and before would strip it. To
23get this fix in we first had to write the test suite to expose current
24behaviour, then change something so that singe $ was passed through, but
25double "$$" got mapped to "$" for backwards compatibility.
26
27
28<h2>Use built in helper classes</h2>
29
30Ant includes helper tasks to simplify much of your work. Be warned that
31these helper classes will look very different in ant2.0 from these 1.x
32versions. However it is still better to use them than roll your own, for
33development, maintenance and code size reasons.
34
35<h4>Execute</h4>
36
37Execute will spawn off separate programs under all the platforms which
38ant supports, dealing with Java version issues as well as platform
39issues. Always use this task to invoke other programs.
40
41<h4>Java, ExecuteJava</h4>
42
43These classes can be used to spawn Java programs in a separate VM (they
44use execute) or in the same VM -with or without a different classloader.
45When deriving tasks from this, it often benefits users to permit the
46classpath to be specified, and for forking to be an optional attribute.
47
48
49<h4>Project and related classes</h4>
50
51Project, FileUtils, JavaEnvUtils all have helper functions
52to do things like touch a file, to
53copy a file and the like. Use these instead of trying to code them
54yourself -or trying to use tasks which may be less stable and fiddlier
55to use.
56
57
58<h2>Obey the Sun/Java style guidelines</h2>
59
60The Ant codebase aims to have a single unified coding standard, and that
61standard is the
62<a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">
63Sun Java coding guidelines
64</a>
65<p>
66
67It's not that they are better than any alternatives, but they are a
68standard and they are what is consistently used in the rest of the
69tasks. Code will not be incorporated into the database until it complies
70with these.
71
72<p>
73
74If you are writing a task for your personal or organisational use, you
75are free to use whatever style you like. But using the Sun Java style
76will help you to become comfortable with the rest of the Ant source,
77which may be important.
78
79<p>
80
81One important rule is 'no tabs'. Use four spaces instead. Not two,
82not eight, four. Even if your editor is configured to have a tab of four
83spaces, lots of others aren't -spaces have more consistency across
84editors and platforms. Some IDEs (JEdit) can highlight tabs, to stop you
85accidentally inserting them
86<p>
87There is an ant build file check.xml in the main ant directory with runs
88 <a href="http://checkstyle.sourceforge.net">checkstyle</a> over
89 ant's source code.
90
91<h2>Attributes and elements</h2>
92Use the Ant introspection based mapping of attributes into Java datatypes,
93rather than implementing all your attributes as setFoo(String) and doing
94the mapping to Int, bool or file yourself. This saves work on your part,
95lets Java callers use you in a typesafe manner, and will let the Xdocs
96documentation generator work out what the parameters are.
97
98<p>
99The ant1.x tasks are very inconsistent regarding naming of attributes
100-some tasks use <tt>source</tt>, others <tt>src</tt>.
101Here is a list of preferred attribute names.
102
103<table border="1" cellpadding="2" cellspacing="0">
104<tr>
105<td>
106 failonerror
107</td>
108<td>
109 boolean to control whether failure to execute should throw a
110 <tt>BuildException</tt> or just print an error.
111 Parameter validation failures should always throw an error, regardless
112 of this flag
113</td>
114</tr>
115<tr>
116<td>
117 destdir
118</td>
119<td>
120 destination directory for output
121</td>
122</tr>
123<td>
124 destfile
125</td>
126<td>
127 destination file for output
128</td>
129</tr>
130<tr>
131<td>
132 srcdir
133</td>
134<td>
135 source directory
136</td>
137</tr>
138<tr>
139<td>
140 srcfile
141</td>
142<td>
143 source file
144</td>
145</tr>
146</table>
147Yes, this is a very short list. Try and be vaguely consistent with the core
148tasks, at the very least.
149
150<h2>Support classpaths</h2>
151
152Try and make it possible for people to supply a classpath to your task,
153if you need external libraries, rather than make them add everything to
154the ANT_HOME\lib directory. This lets people keep the external libraries
155in their ant-based project, rather than force all users to make changes
156to their ant system configuration.
157
158<h2>Design for controlled re-use</h2>
159
160Keep member variables private. If read access by subclasses is required.
161add accessor methods rather than change the accessiblity of the member.
162This enables subclasses to access the contents, yet
163still be decoupled from the actual implementation.
164<p>
165
166The other common re-use mechanism in ant is for one task to create and
167configure another. This is fairly simple.
168
169<h2>Do your own Dependency Checking</h2>
170
171Make has the edge over Ant in its integrated dependency checking: the
172command line apps make invokes dont need to do their own work. Ant tasks
173do have to do their own dependency work, but if this can be done then
174it can be done well. A good dependency aware task can work out the dependencies
175without explicit dependency information in the build file, and be smart
176enough to work out the real dependencies, perhaps through a bit of file parsing.
177The <tt>depends</tt> task is the best example of this. Some of the zip/jar
178tasks are pretty good too, as they can update the archive when needed.
179Most tasks just compare source and destination timestamps and work from there.
180Tasks which don't do any dependency checking do not help users as much as
181they can, because their needless work can trickle through the entire build, test
182and deploy process.
183
184<h2>Support Java 1.2 through Java 1.4</h2>
185
186Ant1.5 and lower was designed to support Java1.1. Ant1.6 and higher
187is designed to support Java1.2: to build on it, to run on it. Sometimes
188functionality of tasks have to degrade in that environment
189- this is usually due to library limitations;
190such behaviour change must always be noted in the documentation.
191<p>
192What is problematic is code which is dependent on Java1.3 features
193-java.lang.reflect.Proxy, or Java1.4 features - java.io.nio for example.
194Be also aware of extra
195methods in older classes - like StringBuffer#append(StringBuffer).
196These can not be used directly by any code and still be able to compile
197and run on a Java 1.2 system.
198If a new method in an existing class
199is to be used, it must be used via reflection and the
200<tt>NoSuchMethodException</tt> handled somehow.
201<p>
202What if code simply does not work on Java1.2? It can happen. It will
203probably be OK to have the task as an optional task, with compilation
204restricted to Java1.3 or later through build.xml modifications.
205Better still, use reflection to link to the classes at run time.
206<p>
207Java 1.4 adds a new optional change to the language itself, the
208<tt>assert</tt> keyword, which is only enabled if the compiler is told
209to compile 1.4 version source. Clearly with the 1.2 compatibility requirement,
210Ant tasks can not use this keyword. They also need to move away from
211using the JUnit <tt>assert()</tt> method and call <tt>assertTrue()</tt>
212instead.
213<p>
214Java 1.5 will (perhaps) add a new keyword - enum, one should avoid
215this for future compatibility.
216
217
218<h2>Refactor</h2>
219
220If the changes made to a task are making it too unwieldy, split it up
221into a cleaner design, refactor the code and submit not just feature
222creep but cleaner tasks. A common design pattern which tends to occur in
223the ant process is the adoption of the adapter pattern, in which a base
224class (say Javac or Rmi) starts off simple, then gets convoluted with
225support for multiple back ends -javac, jikes, jvc. A refactoring to
226split the programmable front end from the classes which provide the back
227end cleans up the design and makes it much easier to add new back ends.
228But to carry this off one needs to keep the interface and behaviour of
229the front end identical, and to be sure that no subclasses have been
230accessing data members directly -because these data members may not
231exist in the refactored design. Which is why having private data members
232is so important.
233
234
235<h2>Test</h2>
236
237Look in <tt>ant/src/testcases</tt> and you will find JUnit tests for the
238shipping ant tasks, to see how it is done and what is expected of a new
239task. Most of them are rudimentary, and no doubt you could do better for
240your task -feel free to do so!
241
242<p>
243
244A well written set of test cases will break the Ant task while it is in
245development, until the code is actually complete. And every bug which
246surfaces later should have a test case added to demonstrate the problem,
247and to fix it.
248
249<p>
250
251The test cases are a great way of testing your task during development.
252A simple call to 'build run-test' in the ant source tree will run all ant
253tests, to verify that your changes don't break anything.
254To test a single task, use the one shot <code>ant run-single-test
255-Dtestcase=${testname}</code> where <code>${testname}</code> is the name of your test class.
256
257
258<p>
259
260The test cases are also used by the committers to verify that changes
261and patches do what they say. If you've got test cases it increases your
262credibility significantly. To be precise, we hate submissions without
263test cases, as it means we have to write them ourselves. This is
264something that only gets done if we need the task or it is perceived as
265utterly essential to many users.
266
267<p>
268
269Remember also that Ant 1.x is designed to compile and run on Java1.2, so
270you should test on Java 1.2 as well as any later version which you use.
271You can download an old SDK from Sun for this purpose.
272<p>
273Finally, run a full <code>build test</code> before and after you start
274developing your project, to make sure you havent broken anything else by
275accident.
276
277<h2>Document</h2>
278
279Without documentation, the task can't be used. So remember to provide a
280succint and clear html (soon, xml) page describing the task in a similar
281style to that of existing tasks. It should include a list of attributes
282and elements, and at least one working example of the task. Many users
283cut and paste the examples into their build files as a starting point,
284so make the examples practical and test them too.
285<p>
286You can use the xdocs stuff in proposal/xdocs to autogenerate your
287documentation page from the javadocs of the source; this makes life
288easier and will make the transition to a full xdoclet generated
289documentation build process trivial.
290
291<h2>Licensing and Copyright</h2>
292
293Any code submitted to the Apache project must be compatible with the
294Apache Software License, and the act of submission must be viewed as an
295implicit transfer of ownership of the submitted code to the Apache
296Software Foundation.
297
298<p>
299This is important.
300
301<p>
302
303The fairly laissez-faire license of Apache is not compabitible with
304either the GPL or the Lesser GPL of the Free Software Foundation -the
305Gnu project. These licenses have stricter terms, "copyleft", which are
306not in the Apache Software Foundation license.
307This permits people and organisations to build
308commercial and closed source applications atop the Apache libraries and
309source -but not use the Apache, Ant or Jakarta Project names without
310permission.
311
312<p>
313
314Because the Gnu GPL license immediately extends to cover any larger
315application (or library, in the case of GLPL) into which it is
316incorporated, the Ant team can not incorporate any task based upon GPL
317or LGPL source into the Ant codebase. You are free to submit it, but it
318will be politely and firmly rejected.
319
320<p>
321
322Once ant-2 adds better dynamic task incorporation, it may be possible to
323provide a framework for indirectly supporting [L]GPL code, but still no tasks
324directly subject to the Gnu licenses can be included in the Ant
325CVS tree.
326
327<p>
328If you link to a GPL or LGPL library, by <code>import</code> or
329reflection, your task must be licensed under the same terms. So tasks
330linking to (L)GPL code can't go into the Apache managed codebase.
331Tasks calling such code can use the 'exec' or 'java' tasks to run the
332programs, as you are just executing them at this point, not linking to
333them.
334<p>
335Even if we cannot include your task into the Apache codebase, we can
336still point to where you host it -just submit a diff to
337xdocs/external.html pointing to your task.
338
339If your task links directly to proprietary code, we have a differnt
340problem: it is really hard to build the tasks. Please use reflection.
341
342<h3>Dont re-invent the wheel</h3>
343
344We've all done it: written and submitted a task only to discover it
345was already implemented in a small corner of another task, or it has
346been submitted by someone else and not committed. You can avoid this
347by being aware of what is in the latest CVS tree -keep getting the daily
348source updates, look at manual changes and subscribe to the dev
349mailing list.
350
351<p>
352
353If you are thinking of writing a task, posting a note on your thoughts
354to the list can be informative -you well get other peoples insight and
355maybe some half written task to do the basics, all without writing a
356line of code.
357
358
359<h2>Submitting to Ant</h2>
360
361The process for submitting an Ant task is documented on the
362<a href="http://jakarta.apache.org/site/guidelines.html">
363jakarta web site</a>.
364The basic mechanism is to mail it to the dev mailing list.
365It helps to be on this list, as you will see other submissions, and
366any debate about your own submission.
367<p>
368You may create your patch file using either of the following approaches.
369The committers recommend you to take the first approach.
370<p>
371<ul>
372<li> <h3>Approach 1 - The Ant Way</h3>
373<p>
374Use Ant to generate a patch file to Ant:
375<pre class="code">
376ant -f patch.xml
377</pre>
378This will create a file named patch.tar.gz that will contain a unified
379diff of files that have been modified and also include files that have
380been added. Review the file for completeness and correctness. This approach
381is recommended because it standardizes the way in which patch files are
382constructed. It also eliminates the chance of you missing to submit new files
383that constitute part of the patch.
384<p>
385<li><h3>Approach 2 - The Manual Way</h3>
386<p>
387Patches to existing files should be generated with
388<code>cvs diff -u filename</code>
389 and save the output to a file. If you want to get
390the changes made to multiple files in a directory , just use <code>cvs
391diff -u</code>. Then, Tar and GZip the patch file as well as any new files
392that you have added.
393</ul>
394<p>
395The patches should be sent as an attachment to a message titled [PATCH]
396and distinctive one-line summary in the subject of the patch. The
397filename/task and the change usually suffices. It's important to include
398the changes as an attachment, as too many mailers reformat the text
399pasted in, which breaks the patch.
400<p>
401Then you wait for one of the committers to commit the patch, if it is
402felt appropriate to do so. Bug fixes go in quickly, other changes
403often spark a bit of discussion before a (perhaps revised) commit is
404made.
405<p>
406
407New submissions should be proceeded with [SUBMIT]. The mailer-daemon
408will reject any messages over 100KB, so any large update should be
409zipped up. If your submission is bigger than that, why not break it up
410into separate tasks.
411<p>
412
413We also like submissions to be added to
414<a href="http://nagoya.apache.org/bugzilla/">bugzilla</a>, so that they
415dont get lost. Please submit them by first filing the report with a
416meaningful name, then adding files as attachments. Use CVS diff files
417please!
418<p>
419
420If you hear nothing after a couple of weeks, remind the mailing list.
421Sometimes really good submissions get lost in the noise of other issues.
422This is particularly the case just prior to a new point release of
423the product. At that time anything other than bug fixes will tend
424to be neglected.
425
426<h2>Checklists</h2>
427
428These are the things you should verify before submitting patches and new
429tasks. Things don't have to be perfect, it may take a couple of
430iterations before a patch or submission is committed, and these items
431can be addressed in the process. But by the time the code is committed,
432everything including the documentation and some test cases will have
433been done, so by getting them out the way up front can save time.
434The committers look more favourably on patches and submissions with test
435cases, while documentation helps sell the reason for a task.
436
437<h3>Checklist before submitting a patch</h3>
438<ul>
439<li>Added code complies with style guidelines
440<li>Code compiles and runs on Java1.2
441<li>New member variables are private, and provide public accessor methods
442 if access is actually needed.
443<li>Existing test cases succeed.
444<li>New test cases written and succeed.
445<li>Documentation page extended as appropriate.
446<li>Example task declarations in the documentation tested.
447<li>Diff files generated using cvs diff -u
448<li>Message to dev contains [PATCH], task name and patch reason in
449subject.
450<li>Message body contains a rationale for the patch.
451<li>Message attachment contains the patch file(s).
452</ul>
453
454<h3>Checklist before submitting a new task</h3>
455<ul>
456<li>Java file begins with Apache copyright and license statement.
457<li>Task does not depend on GPL or LGPL code.
458<li>Source code complies with style guidelines
459<li>Code compiles and runs on Java1.2
460<li>Member variables are private, and provide public accessor methods
461 if access is actually needed.
462<li><i>Maybe</i> Task has failonerror attribute to control failure behaviour
463<li>New test cases written and succeed
464<li>Documentation page written
465<li>Example task declarations in the documentation tested.
466<li>Patch files generated using cvs diff -u
467<li>patch files include a patch to defaults.properties to register the
468tasks
469<li>patch files include a patch to coretasklist.html or
470optionaltasklist.html to link to the new task page
471<li>Message to dev contains [SUBMIT] and task name in subject
472<li>Message body contains a rationale for the task
473<li>Message attachments contain the required files -source, documentation,
474test and patches zipped up to escape the HTML filter.
475</ul>
476<hr>
477<p align="center">Copyright &copy; 2001-2003 Apache Software Foundation. All rights
478Reserved.</p>
479
480</body></html>
481
Note: See TracBrowser for help on using the repository browser.