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_in_anger.html 41 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. <head>
  2. <title>
  3. Ant in Anger
  4. </title>
  5. </head>
  6. <body bgcolor="#FFFFFF" text="#000000">
  7. <h1 align="center">Ant in Anger:
  8. </h1>
  9. <h2 align="center">
  10. Using Ant in a Production Development System
  11. </h2>
  12. <h4 align="center">
  13. Steve Loughran
  14. </h4>
  15. <a name="introduction">
  16. <h2>Introduction</h2>
  17. </a>
  18. <a href="http://jakarta.apache.org/ant/">Ant</a>
  19. can be an invaluable tool in a team development process -or it can
  20. be yet another source of problems in that ongoing crises we call
  21. development . This
  22. document contains some strategies and tactics for making the most of
  23. ant. It is moderately frivolous in places, and lacks almost any actual
  24. examples of ant xml. The lack of examples is entirely deliberate -it
  25. keeps document maintenance costs down. Most of the concepts covered
  26. don't need the detail about XML representations, as it is processes we
  27. are concerned about, not syntax. Finally, please be aware that the
  28. comments here are only suggestions which need to be customised to meet
  29. your own needs, not strict rules about what should and should not be
  30. done.
  31. <p>
  32. Firstly, here are some assumptions about the projects which this
  33. document covers
  34. <ul>
  35. <li> Pretty much pure Java, maybe with some legacy cruft on the edges.
  36. <li> Team efforts, usually with the petulant prima-donnas all us Java
  37. programmers become once we realise how much in demand we are.
  38. <li> A fairly distributed development team -spread across locations and
  39. maybe time zones.
  40. <li> Separate sub projects -from separate beans in a big
  41. enterprise application to separate enterprise applications which need to
  42. be vaguely aware of each other.
  43. <li> Significant mismatch between expectations and time available to
  44. deliver. 'Last Week' is the ideal delivery date handed down from above,
  45. late next century the date coming up from below.
  46. <li> Everyone is struggling to keep up with platform and tool evolution.
  47. <li> Extensive use of external libraries, both open and closed source.
  48. </ul>
  49. What that all means is that there is no time to spend getting things
  50. right, you don't have that tight control on how the rest of the team
  51. works and the development process is often more one of chaos minimisation
  52. than anything else. The role of ant in such projects is to ensure that
  53. the build, test and deploy processes run smoothly, leaving you with all
  54. the other problems.
  55. <a name="core">
  56. <h2>Core Practices</h2>
  57. </a>
  58. <h3>
  59. Clarify what you want ant to do</h3>
  60. Ant is not a silver bullet. It is just another rusty bullet in the armory of
  61. development tools available at your disposal. Its primary purpose is to
  62. accelerate the construction and deployment of Java projects. You could certainly
  63. extend ant to do anything Java makes possible -it is easy to imagine writing an
  64. image processing task to help in web site deployment by shrinking and
  65. recompressing jpeg files, for example. But that would be pushing the boundary of
  66. what ant is really intended to do -so should be considered with care.
  67. <P>
  68. Ant is also a great adjunct to an IDE -a way of doing all the housekeeping of
  69. deployment and for clean, automated builds. But a good modern IDE is a
  70. productivity tool in its own right -one you should consider keeping using. Ant
  71. just lets you give the teams somewhat more freedom in IDE choice -&quot;you can
  72. use whatever you want in development, but ant for the deployment
  73. builds&quot;
  74. <h3>
  75. Define standard targets
  76. </h3>
  77. When you have multiple sub projects, define a standard set of targets.
  78. Projects with a split between interface and implementation jar files
  79. could consider <b>impl</b> and <b>intf</b> targets -with separate
  80. <b>debug-impl</b>and <b>debug-intf</b> targets for the debug version.
  81. And of course, the ubiquitous <b>clean</b> target.
  82. <P>
  83. With standard target names, it is easy to build encompassing ant build
  84. files which just hand off the work to the classes below using the
  85. <a href="manual/CoreTasks/ant.html">ant</a>
  86. task. For example. the clean target could be handed down to the <tt>intf</tt> and
  87. <tt>impl</tt> subdirectories from a parent directory
  88. <pre>&lt;target name=&quot;clean&quot; depends=&quot;clean-intf, clean-impl&quot;&gt;
  89. &lt;/target&gt;
  90. &lt;target name=&quot;clean-intf&quot; &gt;
  91. &lt;ant dir=&quot;intf&quot; target=&quot;clean&quot; /&gt;
  92. &lt;/target&gt;
  93. &lt;target name=&quot;clean-impl&quot;&gt;
  94. &lt;ant dir=&quot;impl&quot; target=&quot;clean&quot; /&gt;
  95. &lt;/target&gt; </pre>
  96. If you give targets a <tt>description</tt> tag, then calling <tt>ant
  97. -projecthelp</tt> will list all tasks with their description as 'main targets', and
  98. all tasks without a description as subtargets. Describing all your
  99. entry points is therefore very useful, even before a project becomes big and complicated.
  100. <h3>
  101. Extend ant through new tasks
  102. </h3>
  103. If ant does not do what you want, you can use the
  104. <a href="manual/CoreTasks/exec.html">exec</a> and
  105. <a href="manual/CoreTasks/java.html">java</a> tasks or
  106. <a href="manual/OptionalTasks/script.html">inline scripting</a> to extend it. In a
  107. project with many build.xml files, you soon find that having a single
  108. central place for implementing the functionality keeps maintenance
  109. overhead down. Implementing task extensions through java code seems
  110. extra effort at first, but gives extra benefits:-
  111. <ul>
  112. <li>Cross platform support can be added later without changing any
  113. build.xml files</li>
  114. <li>The code can be submitted to the ant project itself, for other
  115. people to use and maintain</li>
  116. <li>It keeps the build files simpler</li>
  117. </ul>
  118. <h3>
  119. Embrace Automated Testing
  120. </h3>
  121. <b>(alternatively "recriminate early, recriminate often")</b>
  122. <p>
  123. Ant lets you call <a href="manual/OptionalTasks/junit.html">JUnit</a> tasks, which unit test
  124. the code your team has written. Automated testing may seem like extra
  125. work at first, but JUnit makes writing unit tests so easy that you have
  126. almost no reason not to. Invest the time in learning how to use
  127. JUnit, write the test cases, and integrate them in a 'test' target from
  128. ant so that your daily or hourly team build can have the tests applied
  129. automatically.
  130. <p>
  131. Once code fetches from the code control system are added as another ant
  132. target, the integration test code can be a pure ant task run on any box
  133. dedicated to the task. This is ideal for verifying that the build and
  134. unit tests work on different targets from the usual development
  135. machines. For example, a Win95/Java1.1 combination could be used even
  136. though no developer would willingly use that configuration given the
  137. choice.
  138. <p>
  139. System tests are harder to automate than unit tests, but if you can
  140. write java code to stress large portions of the system -even if the code
  141. can not run as JUnit tasks- then the <a href= "manual/CoreTasks/java.html">java</a>
  142. task can be used to invoke them. It is best to specify that you want a
  143. new JVM for these tests, so that a significant crash does not break the
  144. full build. The Junit extensions such as
  145. <a href="http://httpunit.sourceforge.net/">HttpUnit</a> for web pages, and
  146. <a href="http://jakarta.apache.org/commons/cactus/">Cactus</a> for J2EE and servlet
  147. testing help to expand the testing framework. To test properly you will still
  148. need to invest a lot of effort in getting these to work with your project, and
  149. deriving great unit, system and regression tests -but your customers will love
  150. you for shipping software that works.
  151. <a name="crossplatform">
  152. <h2>
  153. Cross Platform Ant
  154. </h2>
  155. </a>
  156. Ant is the best foundation for cross platform Java development and
  157. testing to date. But if you are not paying attention, it is possible to
  158. produce build files which only work on one platform -or indeed, one
  159. single workstation.
  160. <p>
  161. The common barriers to cross-platform ant are the use of command line
  162. tools (exec tasks) which are not portable, path issues, and hard coding
  163. in the location of things.
  164. <h3>Command Line apps: <a href="manual/CoreTasks/exec.html">Exec</a>/ <a href=
  165. "manual/CoreTasks/apply.html">Apply</a></h3>
  166. The trouble with external invocation is that not all functions are found
  167. cross platform, and those that are often have different names -DOS
  168. descendants often expect .exe or .bat at the end of files. That can be
  169. bad if you explicitly include the extension in the naming of the command
  170. (don't!), good when it lets you keep the unix and DOS versions of an
  171. executable in the same bin directory of the project without name
  172. clashes arising.
  173. <p>
  174. Both the command line invocation tasks let you specify which platform
  175. you want the code to run on, so you could write different tasks for each
  176. platform you are targeting. Alternatively, the platform differences
  177. could be handled inside some external code which ant calls. This can be
  178. some compiled down java in a new task, or an external script file.
  179. <h3>Cross platform paths</h3>
  180. Unix paths use forward slashes between directories and a colon to
  181. split entries. Thus
  182. <i>"/bin/java/lib/xerces.jar:/bin/java/lib/ant.jar"</i> is
  183. a path in unix. In Windows the path must use semicolon separators,
  184. colons being used to specify disk drives, and backslash separators
  185. <i>"c:\bin\java\lib\xerces.jar;c:\bin\java\lib\ant.jar"</i>.
  186. <p>
  187. This difference between platforms (indeed, the whole java classpath
  188. paradigm) can cause hours of fun.
  189. <p>
  190. Ant reduces path problems; but does not eliminate them entirely. You
  191. need to put in some effort too. The rules for handling path names are
  192. that 'DOS-like pathnames are handled', 'Unix like paths are handled'.
  193. Disk drives -'C:'- are handled on DOS-based boxes, but placing them in
  194. the build.xml file ruins all chances of portability. Relative file paths
  195. are much more portable. Semicolons work as path separators -a fact which
  196. is useful if your ant invocation wrapper includes a list of jars as a
  197. defined property in the command line. In the build files you may find it
  198. better to build a classpath by listing individual files (using location=
  199. attributes), or by including a fileset of *.jar in the classpath
  200. definition.
  201. <p>
  202. There is also the <a
  203. href="manual/CoreTasks/pathconvert.html">PathConvert</a> task which
  204. can put a fully resolved path into a property. Why do that? Because then
  205. you can use that path in other ways -such as pass it as a parameter to
  206. some application you are calling, or use the replace task to patch it
  207. into a localised shell script or batch file.
  208. <p>
  209. Note that DOS descended file systems are case insensitive (apart from
  210. the obscure aberration of the WinNT posix subsystem run against NTFS),
  211. and that Windows pretends that all file extensions with four or more
  212. letters are also three letter extensions (try DELETE *.jav in your java
  213. directories to see a disastrous example of this).
  214. <p>
  215. Ant's policy on case sensitivity is whatever the underlying file system
  216. implements, and its handling of file extensions is that *.jav does not
  217. find any .java files. The Java compiler is of course case sensitive -you can
  218. not have a class 'ExampleThree' implemented in "examplethree.java".
  219. <p>
  220. Some tasks only work on one platform -<a href= "manual/CoreTasks/chmod.html">
  221. Chmod</a> being a classic example. These tasks usually result in just a
  222. warning message on an unsupported platform -the rest of the target's
  223. tasks will still be called. Other tasks degrade their functionality on
  224. platforms or Java versions. In particular, any task which adjusts the
  225. timestamp of files can not do so properly on Java 1.1. Tasks which can
  226. do that - <a href="manual/CoreTasks/get.html">Get<a>, <a
  227. href="manual/CoreTasks/touch.html">Touch</a> and <A href="manual/CoreTasks/unzip.html">
  228. Unjar/Unwar/Unzip</a> for example, degrade their functionality on
  229. Java1.1, usually resorting to the current timestamp instead.
  230. <p>
  231. Finally, Perl makes a good place to wrap up Java invocations cross
  232. platform, rather than batch files. It is included in most Unix
  233. distributions, and is a simple download for <a href=
  234. "http://www.activestate.com/Products/ActivePerl/"> Win32 platforms from
  235. ActiveState</a>. A Perl file with .pl extension, with the usual Unix
  236. path to perl on the line 1 comment and marked as executable can be run
  237. on Windows, OS/2 and Unix and hence called from Ant without issues. The
  238. perl code can be left to resolve its own platform issues.
  239. <a name="team">
  240. <h2>Team Development Processes</h2>
  241. </a>
  242. Even if each team member is allowed their choice of IDE/editor, or even
  243. OS, you need to set a baseline of functionality on each box. In
  244. particular, the JDKs and jars need to be in perfect sync. Ideally pick
  245. the latest stable Java/JDK version available on all developer/target
  246. systems and stick with it for a while. Consider assigning one person to
  247. be the contact point for all tools coming in -particularly open source
  248. tools when a new build is available on a nightly basis. Unless needed,
  249. these tools should only really be updated monthly, or when a formal
  250. release is made.
  251. <p>
  252. Another good tactic is to use a unified directory tree, and add on extra
  253. tools inside that tree. All references can be made relative to the tree.
  254. If team members are expected to add a directory in the project to their
  255. path, then command line tools can be included there -including those
  256. invoked by ant exec tasks. Put everything under source code control and
  257. you have a one stop shop for getting a build/execute environment purely
  258. from CVS or your equivalent.
  259. <a name="deploying">
  260. <h2>Deploying with Ant</h2>
  261. </a>
  262. One big difference between ant and older tools such as make is that the
  263. processes for deploying java to remote sites are reasonably well
  264. evolved in ant. That is because we all have to do it these days, so
  265. many people have put in the effort to make the tasks easier.
  266. <p>
  267. Ant can <a href="manual/CoreTasks/jar.html">Jar</a>, <a href= "manual/CoreTasks/tar.html">
  268. Tar</a> or <a href="manual/CoreTasks/zip.html">Zip</a> files for deployment, while
  269. the <a href="manual/CoreTasks/war.html">War</a> task extends the jar task for
  270. better servlet deployment. <a href = "jlink.html" >Jlink</a> is a jar
  271. generation file which lets you merge multiple sub jars. This is ideal
  272. for a build process in which separate jars are generated by sub
  273. projects, yet the final output is a merged jar. <a href=
  274. "manual/OptionalTasks/cab.html">Cab</a> can be used on Win32 boxes to build a cab file
  275. which is useful if you have to target IE deployment.
  276. <p>
  277. The <a href = "index.html#ftp">ftp</a> task lets you move stuff up to a
  278. server. Beware of putting the ftp password in the build file -a property
  279. file with tight access control is slightly better. The <a href=
  280. "manual/CoreTasks/fixcrlf.html">FixCRLF task</a> is often a useful interim step if
  281. you need to ensure that files have unix file extensions before upload. A
  282. WebDav task has long been discussed, which would provide a more secure
  283. upload to web servers, but it is still in the todo list. Rumour has it
  284. that there is such a task in the jakarta-slide libraries.
  285. <p>
  286. EJB deployment is aided by the <a href="manual/OptionalTasks/ejb.html">ejb tasks</a>. At the
  287. time of writing, only WebLogic was supported with these tasks -if your
  288. EJB server is not supported, extending the ejb tasks would benefit your
  289. project and the rest of the ant community.
  290. <p>
  291. Finally, there are of course the fallbacks of just copying files to a
  292. destination using <a href="manual/CoreTasks/copy.html">Copy</a> and <a href =
  293. "index.html#copydir">Copydir</a> , or just sending them to a person or
  294. process using <a href= "manual/CoreTasks/mail.html">Mail</a> or the attachment
  295. aware <a href= "manual/OptionalTasks/mimemail.html">MimeMail</a>.
  296. In one project our team even used ant to build CD images through a build followed
  297. by a long set of Copy tasks, which worked surprisingly well.
  298. <a name="directories">
  299. <h2> Directory Structures</h2>
  300. </a>
  301. How you structure your directory tree is very dependent upon the
  302. project. Here are some directory layout patterns which can be used as
  303. starting points. All the jakarta projects follow a roughly similar
  304. style, which makes it easy to navigate around one form one project to
  305. another, and easy to clean up when desired.
  306. <h3>Simple Project</h3>
  307. The project contains sub directories
  308. <table width="100%">
  309. <tr>
  310. <td><b>bin</b>
  311. </td>
  312. <td>common binaries, scripts -put this on the path.
  313. </td>
  314. </tr>
  315. <tr>
  316. <td><b>build</b>
  317. </td>
  318. <td>This is the tree for building; ant creates it and can empty it
  319. in the 'clean' project.
  320. </td>
  321. </tr>
  322. <tr>
  323. <td><b>dist</b>
  324. </td>
  325. <td>Distribution outputs go in here; the directory is created in ant
  326. and clean empties it out
  327. </td>
  328. </tr>
  329. <tr>
  330. <td><b>doc</b>
  331. </td>
  332. <td>Hand crafted documentation
  333. </td>
  334. </tr>
  335. <tr>
  336. <td><b>lib</b>
  337. </td>
  338. <td>Imported Java libraries go in to this directory
  339. </td>
  340. </tr>
  341. <tr>
  342. <td><b>src</b>
  343. </td>
  344. <td>source goes in under this tree <i>in a heirarchy which matches
  345. the package names<i>. The dependency compilation of javac requires this.
  346. </td>
  347. </tr>
  348. </table>
  349. The bin, lib, doc and src directories should be under source code control.
  350. Slight variations include an extra tree of content to be included in the
  351. distribution jars -inf files, images, etc. These can go under source
  352. too, with a <tt>metadata</tt> directory for web.xml and similar
  353. manifests, and a <tt>web</tt> folder for web content -JSP, html, images
  354. and so on. Keeping the content in this folder (or sub heirarchy)
  355. together makes it easier to test links before deployment. The actual
  356. production of a deployment image -such as a war file- can be left to the
  357. appropriate ant task: there is no need to completely model your source tree
  358. upon the deployment heirarchy.
  359. <p>
  360. Javadoc output can be
  361. directed to a doc/ folder beneath build/, or to doc/javadoc.
  362. <h3>Interface and Implementation split</h3>
  363. If the interface is split from the implementation code then this can be
  364. supported with minor changes just by having a separate build path for
  365. the interface directory -or better still just in the jar construction:
  366. one jar for interface and one jar for implementation.
  367. <h3>Loosely Coupled Sub Projects</h3>
  368. In the loosely coupled approach multiple projects can have their own
  369. copy of the tree, with their own source code access rights.
  370. One difference to consider is only having one instance of the bin and
  371. lib directories across all projects. This is sometimes good -it helps
  372. keep copies of xerces.jar in sync, and sometimes bad -it can update
  373. foundational jar files before unit testing is complete.
  374. <p>
  375. To still have a single build across the sub projects, use parent
  376. build.xml files which call down into the sub projects.
  377. <p>
  378. This style works well if different teams have different code
  379. access/commitment rights. The risk is that by giving extra leeway to the
  380. sub projects, you can end up with incompatible source, libraries, build
  381. processes and just increase your workload and integration grief all round.
  382. <p>
  383. The only way to retain control over a fairly loosely integrated
  384. collection of projects is to have a fully automated build
  385. and test process which verifies that everything is still compatible. Sam
  386. Ruby runs one for all the apache java libraries and emails everyone when
  387. something breaks; your own project may be able to make use of
  388. <A href="http://cruisecontrol.sourceforge.net/">Cruise Control</a> for
  389. an automated, continuous, background build process.
  390. <h3>Integrated sub projects</h3>
  391. Tightly coupled projects have all the source in the same tree; different
  392. projects own different subdirectories. Build files can be moved down to
  393. those subdirectores (say src/com/iseran/core and src/com/iseran/extras),
  394. or kept at the top -with independent build files named core.xml and
  395. extras.xml
  396. <p>
  397. This project style works well if everyone trusts each other and the
  398. sub projects are not too huge or complex. The risk is that a split to a
  399. more loosely coupled design will become a requirement as the projects
  400. progress -but by the time this is realised schedule pressure and
  401. intertwined build files make executing the split well nigh impossible.
  402. If that happens then just keep with it until there is the time to
  403. refactor the project directory structures.
  404. <a name="antupdate">
  405. <h2>
  406. Ant Update Policies
  407. </h2>
  408. </a>
  409. Once you start using ant, you should have a policy on when and how the
  410. team updates their copies. A simple policy is "every official release
  411. after whatever high stress milestone has pushed all unimportant tasks
  412. (like sleep and seeing daylight) on the back burner". This insulates you
  413. from the changes and occasional instabilities that ant goes through
  414. during development. Its main disadvantage is that it isolates you from
  415. the new tasks and features that ant is constantly adding.
  416. <p>
  417. Often an update will require changes to the build.xml files. Most
  418. changes are intended to be backwards compatible, but sometimes an
  419. incompatible change turns out to be
  420. necessary. That is why doing the update in the lull after a big
  421. milestone is important. It is also why including ant.jar and related
  422. files in the CVS tree helps ensure that old versions of your software
  423. can be still be built.
  424. <p>
  425. The most aggressive strategy is to get a weekly or daily snapshot of the
  426. ant source, build it up and use it. This forces you to tweak the
  427. build.xml files more regulary, as new tasks and attributes can take
  428. while to stabilise. You really have to want the new features, enjoy
  429. gratuitous extra work or take pleasure in upsetting your colleagues to
  430. take this approach.
  431. <p>
  432. Once you start extending ant with new tasks, it suddenly becomes much
  433. more tempting to pull down regular builds. The most recent ant builds
  434. are invariably the the best platform for writing your extensions, as you
  435. can take advantage of the regular enhancements to the foundational
  436. classes. It also prevents you from wasting time working on something
  437. which has already been done. A newly submitted task to do something
  438. complex such as talk to EJB engines, SOAP servers or just convert a text
  439. file to uppercase may be almost exactly what you need -so take it,
  440. enhance it and offer up the enhancements to the rest of the world. This
  441. is certainly better than starting work on your 'text case converter'
  442. task on Ant 0.8 in isolation, announcing its existence six months latter
  443. and discovering that instead of adulation all you get are helpful
  444. pointers to the existing implementation. The final benefit of being
  445. involved with the process is that it makes it easier for your tasks to
  446. be added with the ant CVS tree, bringing forward the date when ant has
  447. taken on all the changes you needed to make to get your project to work.
  448. If that happens you can revert to an official ant release, and get on
  449. with all the other crises.
  450. <p>
  451. You should also get on the <a href =
  452. "mailto:ant-dev-subscribe@jakarta.apache.org" > ant-dev mailing list
  453. </a>, as it is where the other developers post their work, problems and
  454. experience. The volume can be quite high: 40+ messages a day, so
  455. consider routing it to an email address you don't use for much else. And
  456. don't make everyone on the team subscribe; it can be too much of a
  457. distraction.
  458. <a name="install">
  459. <h2>
  460. Installing with Ant.
  461. </h2>
  462. </a>
  463. Because ant can read environment variables, copy, unzip and delete files
  464. and make java and OS calls, it can be used for simple installation
  465. tasks. For example, an installer for tomcat could extract the
  466. environment variable TOMCAT_HOME, stop tomcat running, and copy a war
  467. file to TOMCAT_HOME/webapps. It could even start tomcat again, but the
  468. build wouldn't complete until tomcat exited, which is probably not what
  469. was wanted.
  470. <p>
  471. The advantage of using ant is firstly that the same install targets
  472. can be used from your local build files (via an <tt>ant</tt> invocation
  473. of the install.xml file), and secondly that a basic install target is
  474. quite easy to write. The disadvantages of this approach are that the
  475. destination must have an up to date version of ant correctly
  476. pre-installed, and ant doesn't allow you to handle failures well -and a
  477. good installer is all about handling when things go wrong, from files
  478. being in use to jar versions being different. This means that ant is not
  479. suited for shrink wrapped software, but it does work for deployment and
  480. installation to your local servers.
  481. <p>
  482. One major build project I was involved in had an ant install build file
  483. for the bluestone application server, which would shutdown all four
  484. instances of the app server on a single machine, copy the new version of
  485. the war file (with datestamp and buildstamp) to an archive directory,
  486. clean up the current deployed version of the war and then install the
  487. new version. Because bluestone restarted JVMs on demand, this script was
  488. all you needed for web service deployment. On the systems behind the
  489. firewall, we upped the ante in the deployment process by using the ftp
  490. task to copy out the war and build files, then the telnet task to
  491. remotely invoke the build file. The result was we had automated
  492. recompile and redeploy to local servers from inside our IDE (Jedit) or
  493. the command line, which was simply invalualbe.
  494. <p>
  495. One extra trick I added later was a junit test case to run through
  496. the install check list. With tests to verify access permissions on network
  497. drives, approximate clock synchronisation between servers, DNS functionality,
  498. ability to spawn executables and all the other trouble spots
  499. , the install script could automatically do
  500. a system health test during install time and report problems. [The same tests
  501. could also be invoked from a JMX MBean, but that's another story].
  502. <p>
  503. So, ant is not a substitute for a real installer tool, except in the
  504. special case of servers you control, but in that context it does let
  505. you integrate remote installation with your build.
  506. <a name="tips">
  507. <h2>
  508. Tips and Tricks</h2>
  509. </a>
  510. <dl>
  511. <dt><b>
  512. get
  513. </b><dd>
  514. The <a href="manual/CoreTasks/get.html">get</a> task can fetch any URL, so be used
  515. to trigger remote server side code during the build process, from remote
  516. server restarts to sending SMS/pager messages to the developer
  517. cellphones.
  518. <dt><b>
  519. i18n
  520. </b><dd>
  521. Internationalisation is always trouble. Ant helps here with the <A href=
  522. "manual/OptionalTasks/native2ascii.html">native2ascii</a> task which can escape out all non
  523. ascii characters into unicode. You can use this to write java files
  524. which include strings (and indeed comments) in your own non-ASCII
  525. language and then use native2ascii to convert to ascii prior to feeding
  526. through javac. The rest of i18n and l12n is left to you...
  527. <dt><b>
  528. Use Property Files
  529. </b><dd>
  530. Use external property files to keep per-user settings out the build
  531. files -especially passwords. Property files can also be used to
  532. dynamically set a number of properties based on the value of a single
  533. property, simply by dyamically generating the property filename from the
  534. source property. They can also be used as a source of constants across
  535. multiple build files.
  536. <dt><b>
  537. Faster compiles with Jikes
  538. </b><dd>
  539. The <a href="http://www.jikes.org/">jikes compiler</a> is usually much
  540. faster than javac, and does dependency checking. Get it. Then set
  541. build.compiler to "jikes" for it to be used in your build files. Better
  542. yet, set the JIKES_HOME environment variable for jikes to automatically
  543. get used, without changing your build files to only work with jikes.
  544. <dt><b>
  545. #include targets to simplify multi build.xml projects
  546. </b><dd>
  547. You can import XML files into a build file using the XML parser itself.
  548. This lets a multi-project development program share code through reference,
  549. rather than cut and paste re-use. It also lets one build up a file of
  550. standard tasks which can be reused over time. Because the import
  551. mechanism is at a level below which ant is aware, treat it as
  552. equivalent to the #include mechanism of the 'legacy' languages C and
  553. C++.
  554. <p>
  555. There are two inclusion mechanisms, an ugly one for all parsers and a
  556. clean one. For now, the ugly
  557. method is the most portable:-
  558. <pre>
  559. &lt;!DOCTYPE project [
  560. &lt;!ENTITY IncludeBuildCore SYSTEM &quot;buildCore.xml&quot;&gt;
  561. &lt;!ENTITY IncludeBuildSecondary SYSTEM &quot;buildSecondary.xml&quot;&gt;
  562. ]&gt;
  563. &lt;target name=&quot;includedBuild&quot;&gt;
  564. &amp;IncludeBuildCore;
  565. &amp;IncludeBuildSecondary;
  566. &lt;/target&gt;
  567. </pre>
  568. The cleaner method using XInclude/Xpath will let you include named
  569. targets from one build file or another, using
  570. <a href="http://www.w3.org/XML/Linking">
  571. the xpointer syntax</a>. You'll need to wait for the W3C proposals
  572. to finalise and the java XML parsers to implement it before
  573. using xpointer references.
  574. <p>
  575. Before you go overboard with using XML inclusion, note that the <tt>ant</tt> task lets
  576. you call any target in any other build file -with all your property settings propagating down to
  577. that target. So you can actually have a suite of utility targets -"deploy-to-stack-a", "email-to-team",
  578. "cleanup-installation" which can be called from any of your main build files, perhaps with subtly changed
  579. parameters. Indeed, after a couple of projects you may be able to create a re-usable core build file which
  580. contains the core targets of a basic java development project -compile, debug, deploy- which project specific
  581. build files call with their own settings. If you can achive this then
  582. you are definately making your way up the software maturity ladder. NB,
  583. <tt>ant</tt> copies all your properties unless the <i>inheritall</i> attribute is set to false. Before that
  584. attribute existed you had to carefully name all property definitions in all build files to prevent unintentional
  585. overwriting of the invoked property by that of the caller, now you just have to remember to set
  586. <tt>inheritall="false"</tt> on all uses of the ant task.
  587. <dt><b>
  588. Implement complex Ant builds through XSL
  589. </b><dd>
  590. XSLT can be used to dynamically generate build.xml files from a source
  591. xml file, with the <a href="manual/CoreTasks/style.html">Style</a> task controlling
  592. the transform. This is the current recommended strategy for creating
  593. complex build files dynamically. However, its use is still apparently
  594. quite rare -which means you will be on the bleeding edge of technology.
  595. <dt><b>
  596. Change the invocation scripts
  597. </b><dd>
  598. By writing your own invocation script -using the DOS, Unix or Perl
  599. script as a starting point- you can modify a ant behavior for an
  600. individual project. For example, you can use an alternate variable to
  601. ANT_HOME as the base, extend the classpath differently, or dynamically
  602. create a new command line property 'project.interfaces' from all .jar
  603. files in an interfaces directory.
  604. <p>
  605. Having a custom invocation script which runs off a CVS controlled
  606. library tree under PROJECT_HOME also lets you control ant versions
  607. across the team -developers can have other copies of ant if they want,
  608. but the CVS tree always contains the jar set used to build your project.
  609. <p>
  610. You can also write wrapper scripts which invoke the existing ant
  611. scripts. This is an easy way to extend them. The wrapper scripts can add
  612. extra definitions and name explicit targets, redefine ANT_HOME and
  613. generally make development easier. Note that "ant" in Windows is really
  614. "ant.bat", so should be invoked from another batch file with a "CALL
  615. ant" statement -otherwise it never returns to your wrapper.
  616. <dt><b>
  617. Write all code so that it can be called from Ant
  618. </b><dd>
  619. This seems a bit strange and idealistic, but what it means is that you should
  620. write all your java code as if it may be called as a library at some point in
  621. future. So do not place calls to <b>System.exit()</b> deep in the code -if you
  622. want to exit a few functions in, raise an exception instead and have
  623. <b>main()</b> deal with it.
  624. <dt><b>
  625. Use Antidote as the invocation tool
  626. </b><dd>
  627. Even if you edit ant files by hand, Antidote makes a good execution tool
  628. because it eliminates the startup time of the JVM, perhaps even some of
  629. the XML parsing delays.
  630. <dt><b>
  631. Use the replace task to programmatic modify text files in your project.
  632. </b><dd>
  633. Imagine your project has some source files -BAT files, ASP pages (!), anything
  634. which needs to be statically customised at compile time for particular
  635. installations, such driven from some properties of the project such as JVM options, or the URL
  636. to direct errors too. The replace task can be used to modify files, substituting text and creating
  637. versions customised for that build or destination. Of course, per-destination customisation
  638. should be delayed until installation, but if you are using ant for the remote installation
  639. that suddenly becomes feasible.
  640. <dt><b>
  641. Use the mailing lists
  642. </b><dd>
  643. There are two
  644. <a href="http://jakarta.apache.org/site/mail.html">mailing lists</a>
  645. related to ant, ant-user and ant-developer. Ant user is where <i>all</i>
  646. questions related to using ant should go. Installation, syntax, code
  647. samples, etc -post your questions there or search the archives for
  648. whether the query has been posted and answered before. Ant-developer
  649. is where ant development takes place -so it is <i>not</i> the place to
  650. post things like "I get a compilation error when I build my project" or
  651. "how do I make a zip file". If you are actually extending ant, on the other
  652. hand, it is the ideal place to ask questions about how to add new tasks, make
  653. changes to existing ones -and to post the results of your work, if you want them
  654. incorporated into the ant source tree.
  655. </dl>
  656. <a name="puttingtogether">
  657. <h2>
  658. Putting it all together
  659. </h2>
  660. </a>
  661. What does an ant build process look like in this world? Assuming a
  662. single directory structure for simplicity, the build file
  663. should contain a number of top level targets
  664. <ul>
  665. <li>build - do an (incremental) build
  666. <li>test - run the junit tests
  667. <li>clean - clean out the output directories
  668. <li>deploy - ship the jars, wars, whatever to the execution system
  669. <li>publish - output the source and binaries to any distribution site
  670. <li>fetch - get the latest source from the cvs tree
  671. <li>docs/javadocs - do the documenation
  672. <li>all - clean, fetch, build, test, docs, deploy
  673. <li>main - the default build process (usually build or build & test)
  674. </ul>
  675. Sub projects 'web', 'bean-1', 'bean-2' can be given their own build
  676. files -web.xml, bean-1.xml, bean-2.xml- with the same entry points.
  677. Extra toplevel tasks related to databases, web site images and the like
  678. should be considered if they are part of the process.
  679. <p>
  680. Debug/release switching can be handled with separate initialisation
  681. targets called before the compile tasks which define the appropriate
  682. properties. Antcall is the trick here, as it allows you to have two paths
  683. of property initialisation in a build file.
  684. <p>
  685. Internal targets should be used to structure the process
  686. <ul>
  687. <li> init - initialise properties, extra-tasks, read in per-user
  688. property files.
  689. <li> init-debug - initialise debug properties
  690. <li> init-release - initialise release properties
  691. <li> compile - do the actual compilation
  692. <li> link/jar - make the jars or equivalent
  693. <li> staging - any pre-deployment process in which the output is dropped
  694. off then tested before being moved to the production site.
  695. </ul>
  696. The switching between debug and release can be done using the 'if' and
  697. 'unless' conditional flags on the targets, so that debug gets called
  698. unless 'project.mode.release' is defined.
  699. <p>
  700. It is useful to define a project name property which can be echoed in
  701. the init task. This lets you work out which ant file is breaking in a
  702. multi file build.
  703. <p>
  704. What goes in to the internal ant tasks depends on your own projects. One
  705. very important tactic is 'keep path redefinition down through
  706. references' - you can reuse paths by giving them an ID and then
  707. referring to them via the 'refid' attribute you should only need to
  708. define a shared classpath once in the file; filesets can be reused
  709. similarly.
  710. <p>
  711. Once you have set up the directory structures, and defined the ant tasks
  712. it is time to start coding. An early priority must be to set up the
  713. automated test process, as that not only helps ensures that the code
  714. works, it verifies that the build process is working.
  715. <p>
  716. And that's it. The build file shouldn't need changing as new source
  717. files get added, only when you want to change the deliverables or part
  718. of the build process. At some point you may want to massively
  719. restructure the entire build process, restructuring projects and the
  720. like, but even then the build file you have should act as a foundation
  721. for a split build file process -just pull out the common properties into
  722. a properties file all build files read in, keep the target names unified
  723. and keep going with the project. Restructuring the source code control
  724. system is often much harder work.
  725. <h2>The Limits of Ant</h2>
  726. Before you start adopting ant as the sole mechanism for the build
  727. process, you need to be aware of what it doesn't do.
  728. <p>
  729. <h3>It's not a scripting language</h3>
  730. Ant lets you declare what you want done, with a bit of testing of the
  731. platform and class libraries first to enable some platform specific
  732. builds to take place. It does not let you specify how to handle things
  733. going wrong (a listener class can do that), or support complex
  734. conditional statements.
  735. <p>
  736. If your build needs to handle exceptions then look at the sound listener
  737. as a simple example of how to write your own listener class. Complex
  738. conditional statements can be handled by having something else do the
  739. tests and then build the appropriate ant task. XSLT can be used for
  740. this.
  741. <h3>It's not Make</h3>
  742. Some of the features of make, specifically inference rules and
  743. dependency checking are not included in ant. That's because they are
  744. 'different' ways of doing a build. Make requires you to state
  745. dependencies and the build steps, ant wants you to state tasks and the
  746. order between them, the tasks themselves can do depedency checking or
  747. not. A full java build using Jikes is so fast that dependency checking
  748. is relatively moot, while many of the other tasks (but not all), compare
  749. the timestamp of the source file with that of the destination file
  750. before acting.
  751. <h3>It's not meant to be a nice language for humans</h3>
  752. XML isn't a nice representation of information for humans. It's a
  753. reasonable representation for programs, and text editors and source code
  754. management systems can all handle it nicely. But a complex ant file can
  755. get ugly because XML is a bit ugly, and a complex build is, well,
  756. complicated. Use XML comments so that the file you wrote last month
  757. still makes sense when you get back to it, and use Antidote to edit the
  758. files if you prefer it.
  759. <h3>You still need all the other foundational bits of a software
  760. project</h3>
  761. If you don't have an source code management system, you are going to end
  762. up hosed. If you don't have everything under SCM, including web pages,
  763. dependent jars, installation files, you are still going to end up hosed,
  764. it's just a question of when it's going to happen.
  765. CVS is effectively free and works well with ant, but Sourcesafe, Perforce,
  766. Clearcase and StarTeam also have ant tasks. These tasks
  767. let you have auto-incrementing build counters, and automated file
  768. update processes.
  769. <p>
  770. You also need some kind of change control process, to resist
  771. uncontrolled feature creep. Bugzilla is a simple and low cost tool for
  772. this, using ant and a continuous test process enables a rapid evolution of code
  773. to adapt to those changes which are inevitable.
  774. <h2>Endpiece</h2>
  775. Software development is meant to be fun. Being in the maelstrom of a
  776. tight project with the stress of integration and trying to code
  777. everything up for an insane deadline can be fun -it is certainly
  778. exhilirating. Adding a bit of automation to the process may make things
  779. less chaotic, and bit less entertaining, but it is a start to putting
  780. you in control of your development process. You can still have fun, you
  781. should just have less to worry about, a shorter build/test/deploy cycle
  782. and more time to spend on feature creep or important things like skiing.
  783. So get out there and have fun!
  784. <a name="reading">
  785. <h2>Further Reading</h2>
  786. </a>
  787. <ul>
  788. <li>
  789. <a
  790. href="http://www.martinfowler.com/articles/continuousIntegration.html">
  791. Continuous Integration</a>; Martin Fowler. <br>
  792. A paper on using ant within a software project
  793. running a continuous integration/testing proces.
  794. <li> Refactoring; Martin Fowler, ISBN: 0201485672 <br>
  795. Covers JUnit as well as tactics for making some headway with the mess of
  796. code you will soon have.
  797. </ul>
  798. <a name="author">
  799. <h3>About the Author</h3>
  800. </a>
  801. Steve Loughran is a research scientist at a corporate R&amp;D lab,
  802. currently on a sabbatical building production web services against
  803. implausible deadlines for the fun of it. Because of those implausible
  804. deadlines, email questions related to this document are generally, and
  805. regretfully unwelcome, unless they are corrections to the content,
  806. advanced discourse on how to evolve software engineering processes to
  807. meet the next generation of challenges, or from someone he knows. Even
  808. then, a timely response is unlikely. Please use the mailing lists
  809. instead.
  810. <hr>
  811. <p align="center">Copyright &copy; 2000, 2001 Apache Software Foundation. All rights
  812. Reserved.</p>
  813. </body>