You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ant_task_guidelines.html 20 KiB

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