source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/docs/ant_in_anger.html@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 48.4 KB
Line 
1<head>
2<title>
3 Ant in Anger
4</title>
5</head>
6
7<body bgcolor="#FFFFFF" text="#000000">
8<h1 align="center">Ant in Anger:
9</h1>
10<h2 align="center">
11 Using Apache Ant in a Production Development System
12</h2>
13
14<h4 align="center">
15Steve Loughran<br>
16Last updated 2005-03-16
17</h4>
18
19<a name="introduction">
20
21<h2>Introduction</h2>
22</a>
23
24<a href="http://ant.apache.org/">Apache Ant</a>
25 can be an invaluable tool in a team development process - or it can
26be yet another source of problems in that ongoing crises we call
27development . This
28document contains some strategies and tactics for making the most of
29Ant. It is moderately frivolous in places, and lacks almost any actual
30examples of Ant XML. The lack of examples is entirely deliberate - it
31keeps document maintenance costs down. Most of the concepts covered
32don't need the detail provided by XML representations, as it is the processes we
33are concerned about, not the syntax. Finally, please be aware that the
34comments here are only suggestions which need to be customised to meet
35your own needs, not strict rules about what should and should not be
36done.
37
38<p>
39Firstly, here are some assumptions about the projects which this
40document covers:
41<ul>
42<li> Pretty much pure Java, maybe with some legacy cruft on the edges.
43
44<li> Team efforts, usually with the petulant prima-donnas all us Java
45programmers become once we realise how much in demand we are.
46
47<li> A fairly distributed development team - spread across locations and
48maybe time zones.
49
50<li> Separate sub projects - from separate beans in a big
51enterprise application to separate enterprise applications which need to
52be vaguely aware of each other.
53
54<li> Significant mismatch between expectations and time available to
55deliver. 'Last Week' is the ideal delivery date handed down from above,
56late next century the date coming up from below.
57
58<li> Everyone is struggling to keep up with platform and tool evolution.
59
60<li> Extensive use of external libraries, both open and closed source.
61</ul>
62
63What that all means is that there is no time to spend getting things
64right, you don't have that tight control on how the rest of the team
65works and the development process is often more one of chaos minimisation
66than anything else. The role of Ant in such projects is to ensure that
67the build, test and deploy processes run smoothly, leaving you with all
68the other problems.
69
70<a name="core">
71<h2>Core Practices</h2>
72</a>
73<h3>
74Clarify what you want Ant to do</h3>
75
76Ant is not a silver bullet. It is just another rusty bullet in the armory of
77development tools available at your disposal. Its primary purpose is to
78accelerate the construction and deployment of Java projects. You could certainly
79extend Ant to do anything Java makes possible: it is easy to imagine writing an
80image processing task to help in web site deployment by shrinking and
81recompressing jpeg files, for example. But that would be pushing the boundary of
82what Ant is really intended to do - so should be considered with care.
83
84<p>
85Ant is also a great adjunct to an IDE; a way of doing all the housekeeping of
86deployment and for clean, automated builds. But a good modern IDE is a
87productivity tool in its own right - one you should continue to use. Ant
88just lets you give the teams somewhat more freedom in IDE choice - &quot;you can
89use whatever you want in development, but Ant for the deployment
90builds&quot; Now that many modern open source and commercial IDEs
91include Ant support (including jEdit, Forte, Eclipse and IDEA),
92developers can use a great IDE, with Ant providing a rigorous and portable
93build process integrated into the tool.
94
95<h3>
96Define standard targets
97</h3>
98
99When you have multiple sub projects, define a standard set of targets.
100Projects with a split between interface and implementation jar files
101could consider <b>impl</b> and <b>intf</b> targets - with separate
102<b>debug-impl</b> and <b>debug-intf</b> targets for the debug version.
103And of course, the ubiquitous <b>clean</b> target.
104
105<p>
106
107With standard target names, it is easy to build encompassing Ant build
108files which just hand off the work to the classes below using the
109<a href="manual/CoreTasks/ant.html">ant</a>
110task. For example. the clean target could be handed down to the <tt>intf</tt> and
111<tt>impl</tt> subdirectories from a parent directory
112
113<pre>&lt;target name=&quot;clean&quot; depends=&quot;clean-intf, clean-impl&quot;&gt;
114&lt;/target&gt;
115
116&lt;target name=&quot;clean-intf&quot; &gt;
117 &lt;ant dir=&quot;intf&quot; target=&quot;clean&quot; /&gt;
118&lt;/target&gt;
119
120&lt;target name=&quot;clean-impl&quot;&gt;
121 &lt;ant dir=&quot;impl&quot; target=&quot;clean&quot; /&gt;
122&lt;/target&gt; </pre>
123
124If you give targets a <tt>description</tt> tag, then calling <tt>ant
125-projecthelp</tt> will list all tasks with their description as 'main targets', and
126all tasks without a description as subtargets. Describing all your
127entry points is therefore very useful, even before a project becomes big and complicated.
128
129<h3>
130 Extend Ant through new tasks
131</h3>
132
133If Ant does not do what you want, you can use the
134<a href="manual/CoreTasks/exec.html">exec</a> and
135<a href="manual/CoreTasks/java.html">java</a> tasks or
136<a href="manual/OptionalTasks/script.html">inline scripting</a> to extend it. In a
137project with many <tt>build.xml</tt> files, you soon find that having a single
138central place for implementing the functionality keeps maintenance
139overhead down. Implementing task extensions through Java code seems
140extra effort at first, but gives extra benefits:-
141
142<ul>
143<li>Cross platform support can be added later without changing any
144<tt>build.xml</tt> files</li>
145
146<li>The code can be submitted to the Ant project itself, for other
147people to use and maintain</li>
148
149<li>It keeps the build files simpler</li>
150</ul>
151
152In a way, it is this decoupling of functionality, "the tasks", from
153the declaration of use, "the build file", that has helped Ant succeed.
154If you have to get something complex done in Make or an IDE, you have a
155hairy makefile that everyone is scared of, or an IDE configuration that
156is invariably very brittle. But an Ant task is reusable and shareable
157among all Ant users. Many of the core and optional tasks in Ant today,
158tasks you do or will come to depend on, were written by people trying to
159solve their own pressing problems.
160
161<h3>
162Embrace Automated Testing
163</h3>
164
165<b>(alternatively "recriminate early, recriminate often")</b>
166<p>
167Ant lets you call <a href="manual/OptionalTasks/junit.html">JUnit</a>
168tasks, which unit test the code your team has written. Automated testing
169may seem like extra work at first, but JUnit makes writing unit tests so
170easy that you have almost no reason not to. Invest the time in learning
171how to use JUnit, write the test cases, and integrate them in a 'test'
172target from Ant so that your daily or hourly team build can have the
173tests applied automatically. One of the free to download chapters of
174<a href="http://manning.com/hatcher">Java Development with Ant</a>
175shows you how to use JUnit from inside Ant.
176
177<p>
178Once you add a way to fetch code from the SCM system, either as an Ant
179task, in some shell script or batch file or via some continuous
180integration tool. the integration test code can be a pure Ant task run
181on any box dedicated to the task. This is ideal for verifying that the
182build and unit tests work on different targets from the usual
183development machines. For example, a Win95/Java1.1 combination could be
184used even though no developer would willingly use that configuration
185given the choice.
186
187<p>
188System tests are harder to automate than unit tests, but if you can
189write java code to stress large portions of the system - even if the code
190can not run as JUnit tasks - then the <a href= "manual/CoreTasks/java.html">java</a>
191task can be used to invoke them. It is best to specify that you want a
192new JVM for these tests, so that a significant crash does not break the
193full build. The Junit extensions such as
194<a href="http://httpunit.sourceforge.net/">HttpUnit</a> for web pages, and
195<a href="http://jakarta.apache.org/cactus/">Cactus</a> for J2EE and servlet
196testing help to expand the testing framework. To test properly you will still
197need to invest a lot of effort in getting these to work with your project, and
198deriving great unit, system and regression tests - but your customers will love
199you for shipping software that works.
200
201<h3>Learn to Use and love the add-ons to Ant</h3>
202The Ant distribution is not the limit of the Ant universe, it is only
203the beginning. Look at the
204<a href="http://ant.apache.org/external.html">
205External Tools and Tasks page
206</a> for an up to date list. Here are some of them that .
207
208<ul>
209<li>
210<a href="http://checkstyle.sourceforge.net/">Checkstyle</a><br>
211This tool audits your code and generates HTML reports of wherever any
212style rule gets broken. Nobody can hide from the code police now! tip:
213start using this early, so there's less to correct.</li>
214<li>
215<a href="http://ant-contrib.sf.net/">Ant-contrib</a><br>
216This sourceforge project contains helper tasks that are kept separate
217from core Ant for ideological purity; the foreach and trycatch tasks in
218particular. These give you iteration and extra error handling. Also on
219the site is the &lt;cc&gt; task suite, that compile and link native code
220on a variety of platforms.</li>
221<li>
222<a href="http://xdoclet.sourceforge.net/">XDoclet</a>
223XDoclet adds attributed oriented programming to Java. By adding javadoc
224tags to your code you can have XDoclet automatically generate <tt>web.xml</tt>
225descriptors, taglib descriptors, EJB interfaces, JMX interface classes,
226Castor XML/SQL bindings, and many more. The key here is that all those
227fiddly little XML files you need to create, and those interfaces EJB and
228JMX requires to implement, all can be autogenerated from your Java
229code with a few helper attributes. This reduces
230errors and means you can change your code and have the rest of the app
231take its cue from the source. Never do EJB, JMX or webapps without it!
232</li>
233</ul>
234
235<a name="crossplatform">
236<h2>
237Cross Platform Ant
238</h2>
239</a>
240Ant is the best foundation for cross platform Java development and
241testing to date. But if you are not paying attention, it is possible to
242produce build files which only work on one platform - or indeed, one
243single workstation.
244
245<p>
246The common barriers to cross-platform Ant are the use of command line
247tools (exec tasks) which are not portable, path issues, and hard coding
248in the location of things.
249
250<h3>Command Line apps: <a href="manual/CoreTasks/exec.html">Exec</a> /
251 <a href= "manual/CoreTasks/apply.html">Apply</a></h3>
252
253The trouble with external invocation is that not all functions are found
254cross platform, and those that are often have different names - DOS
255descendants often expect <tt>.exe</tt> or <tt>.bat</tt> at the end of files. That can be
256bad if you explicitly include the extension in the naming of the command
257(don't!), good when it lets you keep the unix and DOS versions of an
258executable in the same bin directory of the project without name
259clashes arising.
260
261<p>
262Both the command line invocation tasks let you specify which platform
263you want the code to run on, so you could write different tasks for each
264platform you are targeting. Alternatively, the platform differences
265could be handled inside some external code which Ant calls. This can be
266some compiled down java in a new task, or an external script file.
267
268<h3>Cross platform paths</h3>
269
270Unix paths use forward slashes between directories and a colon to
271split entries. Thus
272<i>"/bin/java/lib/xerces.jar:/bin/java/lib/ant.jar"</i> is
273a path in unix. In Windows the path must use semicolon separators,
274colons being used to specify disk drives, and backslash separators
275<i>"c:\bin\java\lib\xerces.jar;c:\bin\java\lib\ant.jar"</i>.
276<p>
277This difference between platforms (indeed, the whole java classpath
278paradigm) can cause hours of fun.
279
280<p>
281Ant reduces path problems; but does not eliminate them entirely. You
282need to put in some effort too. The rules for handling path names are
283that 'DOS-like pathnames are handled', 'Unix like paths are handled'.
284Disk drives -'C:'- are handled on DOS-based boxes, but placing them in
285the <tt>build.xml</tt> file ruins all chances of portability. Relative file paths
286are much more portable. Semicolons work as path separators - a fact which
287is useful if your Ant invocation wrapper includes a list of jars as a
288defined property in the command line. In the build files you may find it
289better to build a classpath by listing individual files (using location=
290attributes), or by including a fileset of <tt>*.jar</tt> in the classpath
291definition.
292<p>
293There is also the <a
294href="manual/CoreTasks/pathconvert.html">PathConvert</a> task which
295can put a fully resolved path into a property. Why do that? Because then
296you can use that path in other ways - such as pass it as a parameter to
297some application you are calling, or use the replace task to patch it
298into a localised shell script or batch file.
299<p>
300Note that DOS descended file systems are case insensitive (apart from
301the obscure aberration of the WinNT POSIX subsystem run against NTFS),
302and that Windows pretends that all file extensions with four or more
303letters are also three letter extensions (try <tt>DELETE *.jav</tt> in your java
304directories to see a disastrous example of this).
305
306<p>
307Ant's policy on case sensitivity is whatever the underlying file system
308implements, and its handling of file extensions is that <tt>*.jav</tt> does not
309find any <tt>.java</tt> files. The Java compiler is of course case sensitive - you can
310not have a class 'ExampleThree' implemented in "examplethree.java".
311
312<p>
313Some tasks only work on one platform - <a href= "manual/CoreTasks/chmod.html">
314Chmod</a> being a classic example. These tasks usually result in just a
315warning message on an unsupported platform - the rest of the target's
316tasks will still be called. Other tasks degrade their functionality on
317platforms or Java versions. In particular, any task which adjusts the
318timestamp of files can not do so properly on Java 1.1. Tasks which can
319do that - <a href="manual/CoreTasks/get.html">Get</a>, <a
320href="manual/CoreTasks/touch.html">Touch</a> and <A href="manual/CoreTasks/unzip.html">
321Unjar/Unwar/Unzip</a> for example, degrade their functionality on
322Java1.1, usually resorting to the current timestamp instead.
323
324<p>
325Finally, Perl makes a good place to wrap up Java invocations cross
326platform, rather than batch files. It is included in most Unix
327distributions, and is a simple download for <a href=
328"http://www.activestate.com/Products/ActivePerl/">Win32 platforms from
329ActiveState</a>. A Perl file with <tt>.pl</tt> extension, the usual Unix
330path to perl on the line 1 comment and marked as executable can be run
331on Windows, OS/2 and Unix and hence called from Ant without issues. The
332perl code can be left to resolve its own platform issues. Don't forget to
333set the line endings of the file to the appropriate platform when you
334redistribute Perl code; <a
335href="manual/CoreTasks/fixcrlf.html">fixCRLF</a>
336can do that for you.
337
338<a name="team">
339<h2>Team Development Processes</h2>
340</a>
341Even if each team member is allowed their choice of IDE/editor, or even
342OS, you need to set a baseline of functionality on each box. In
343particular, the JDKs and jars need to be in perfect sync. Ideally pick
344the latest stable Java/JDK version available on all developer/target
345systems and stick with it for a while. Consider assigning one person to
346be the contact point for all tools coming in - particularly open source
347tools when a new build is available on a nightly basis. Unless needed,
348these tools should only really be updated monthly, or when a formal
349release is made.
350
351<p>
352Another good tactic is to use a unified directory tree, and add on extra
353tools inside that tree. All references can be made relative to the tree.
354If team members are expected to add a directory in the project to their
355path, then command line tools can be included there - including those
356invoked by Ant exec tasks. Put everything under source code control and
357you have a one stop shop for getting a build/execute environment purely
358from CVS or your equivalent.
359
360<a name="deploying">
361<h2>Deploying with Ant</h2>
362</a>
363One big difference between Ant and older tools such as Make is that the
364processes for deploying Java to remote sites are reasonably well
365evolved in Ant. That is because we all have to do it these days, so
366many people have put in the effort to make the tasks easier.
367<p>
368Ant can <a href="manual/CoreTasks/jar.html">Jar</a>, <a href=
369"manual/CoreTasks/tar.html">Tar</a> or <a
370href="manual/CoreTasks/zip.html">Zip</a> files for deployment, while the
371<a href="manual/CoreTasks/war.html">War</a> task extends the jar task
372for better servlet deployment.
373<a href ="manual/OptionalTasks/jlink.html">Jlink</a> is a
374jar generation file which lets you merge multiple sub jars. This is
375ideal for a build process in which separate jars are generated by sub
376projects, yet the final output is a merged jar. <a href=
377"manual/OptionalTasks/cab.html">Cab</a> can be used on Win32 boxes to
378build a cab file which is useful if you still have to target IE deployment.
379
380<p>
381The <a href="index.html#ftp">ftp</a> task lets you move stuff up to a
382server. Beware of putting the ftp password in the build file - a property
383file with tight access control is slightly better. The <a href=
384"manual/CoreTasks/fixcrlf.html">FixCRLF</a> task is often a useful interim step if
385you need to ensure that files have Unix file extensions before upload. A
386WebDav task has long been discussed, which would provide a more secure
387upload to web servers, but it is still in the todo list. Rumour has it
388that there is such a task in the jakarta-slide libraries. With MacOS X,
389Linux and Windows XP all supporting WebDAV file systems, you may even be able
390to use <a href="manual/CoreTasks/copy.html">copy</a> to deploy
391though a firewall.
392
393<p>
394EJB deployment is aided by the <a href="manual/OptionalTasks/ejb.html">ejb</a> tasks,
395while the
396<a
397href="manual/OptionalTasks/serverdeploy.html">serverdeploy</a>
398suite can deploy to multiple servers. The popularity of Ant has
399encouraged vendors to produce their own deployment tasks which they
400redistribute with their servers. For example, the Tomcat4.1 installation
401includes tasks to deploy, undeploy and reload web applications.
402
403<p>
404Finally, there are of course the fallbacks of just copying files to a
405destination using <a href="manual/CoreTasks/copy.html">Copy</a> and <a href="index.html#copydir">Copydir</a> , or just sending them to a person or
406process using <a href="manual/CoreTasks/mail.html">Mail</a> or the attachment
407aware <a href= "manual/OptionalTasks/mimemail.html">MimeMail</a>.
408In one project our team even used Ant to build CD images through a build followed
409by a long set of Copy tasks, which worked surprisingly well, certainly
410easier than when we mailed them to the free email service on
411myrealbox.com, then pulled them down from the far end's web browser, which we
412were running over WinNT remote desktop connection, that being tunneled
413through SSH.
414
415<a name="directories">
416<h2> Directory Structures</h2>
417</a>
418
419How you structure your directory tree is very dependent upon the
420project. Here are some directory layout patterns which can be used as
421starting points. All the jakarta projects follow a roughly similar
422style, which makes it easy to navigate around one from one project to
423another, and easy to clean up when desired.
424
425<h3>Simple Project</h3>
426
427The project contains sub directories
428<table width="100%">
429<tr>
430 <td><b>bin</b>
431 </td>
432 <td>common binaries, scripts - put this on the path.
433 </td>
434</tr>
435
436<tr>
437 <td><b>build</b>
438 </td>
439 <td>This is the tree for building; Ant creates it and can empty it
440 in the 'clean' project.
441 </td>
442</tr>
443<tr>
444 <td><b>dist</b>
445 </td>
446 <td>Distribution outputs go in here; the directory is created in Ant
447 and clean empties it out
448 </td>
449</tr>
450<tr>
451 <td><b>doc</b>
452 </td>
453 <td>Hand crafted documentation
454 </td>
455</tr>
456<tr>
457 <td><b>lib</b>
458 </td>
459 <td>Imported Java libraries go in to this directory
460 </td>
461</tr>
462<tr>
463 <td><b>src</b>
464 </td>
465 <td>source goes in under this tree <i>in a hierarchy which matches
466 the package names<i>. The dependency rules of &lt;javac&gt; requires this.
467 </td>
468</tr>
469</table>
470
471The bin, lib, doc and src directories should be under source code control.
472Slight variations include an extra tree of content to be included in the
473distribution jars - inf files, images, etc. These can go under source
474too, with a <tt>metadata</tt> directory for <tt>web.xml</tt> and similar
475manifests, and a <tt>web</tt> folder for web content - JSP, html, images
476and so on. Keeping the content in this folder (or sub hierarchy)
477together makes it easier to test links before deployment. The actual
478production of a deployment image, such as a war file, can be left to the
479appropriate Ant task: there is no need to completely model your source tree
480upon the deployment hierarchy.
481<p>
482Javadoc output can be
483directed to a <tt>doc/</tt> folder beneath <tt>build/</tt>, or to <tt>doc/javadoc</tt>.
484
485<h3>Interface and Implementation split</h3>
486
487If the interface is split from the implementation code then this can be
488supported with minor changes just by having a separate build path for
489the interface directory - or better still just in the jar construction:
490one jar for interface and one jar for implementation.
491
492<h3>Loosely Coupled Sub Projects</h3>
493
494In the loosely coupled approach multiple projects can have their own
495copy of the tree, with their own source code access rights.
496One difference to consider is only having one instance of the bin and
497lib directories across all projects. This is sometimes good - it helps
498keep copies of xerces.jar in sync, and sometimes bad - it can update
499foundational jar files before unit testing is complete.
500
501<p>
502To still have a single build across the sub projects, use parent
503<tt>build.xml</tt> files which call down into the sub projects.
504<p>
505This style works well if different teams have different code
506access/commitment rights. The risk is that by giving extra leeway to the
507sub projects, you can end up with incompatible source, libraries, build
508processes and just increase your workload and integration grief all round.
509<p>
510The only way to retain control over a fairly loosely integrated
511collection of projects is to have a fully automated build
512and test process which verifies that everything is still compatible. Sam
513Ruby runs one for all the apache java libraries and emails everyone when
514something breaks; your own project may be able to make use of
515<A href="http://cruisecontrol.sourceforge.net/">Cruise Control</a> for
516an automated, continuous, background build process.
517
518<h3>Integrated sub projects</h3>
519
520Tightly coupled projects have all the source in the same tree; different
521projects own different subdirectories. Build files can be moved down to
522those subdirectories (say <tt>src/com/iseran/core</tt> and <tt>src/com/iseran/extras</tt>),
523or kept at the top - with independent build files named <tt>core.xml</tt> and
524<tt>extras.xml</tt>.
525
526<p>
527This project style works well if everyone trusts each other and the
528sub projects are not too huge or complex. The risk is that a split to a
529more loosely coupled design will become a requirement as the projects
530progress - but by the time this is realised schedule pressure and
531intertwined build files make executing the split well nigh impossible.
532If that happens then just keep with it until there is the time to
533refactor the project directory structures.
534
535<a name="antupdate">
536<h2>
537 Ant Update Policies
538</h2>
539</a>
540
541Once you start using Ant, you should have a policy on when and how the
542team updates their copies. A simple policy is &quot;every official release
543after whatever high stress milestone has pushed all unimportant tasks
544(like sleep and seeing daylight) on the back burner&quot;. This insulates you
545from the changes and occasional instabilities that Ant goes through
546during development. Its main disadvantage is that it isolates you from
547the new tasks and features that Ant is constantly adding.
548
549<p>
550Often an update will require changes to the <tt>build.xml</tt> files. Most
551changes are intended to be backwards compatible, but sometimes an
552incompatible change turns out to be
553necessary. That is why doing the update in the lull after a big
554milestone is important. It is also why including <tt>ant.jar</tt> and related
555files in the CVS tree helps ensure that old versions of your software
556can be still be built.
557
558<p>
559The most aggressive strategy is to get a weekly or daily snapshot of the
560ant source, build it up and use it. This forces you to tweak the
561<tt>build.xml</tt> files more regularly, as new tasks and attributes can take
562while to stabilise. You really have to want the new features, enjoy
563gratuitous extra work or take pleasure in upsetting your colleagues to
564take this approach.
565
566<p>
567Once you start extending Ant with new tasks, it suddenly becomes much
568more tempting to pull down regular builds. The most recent Ant builds
569are invariably the best platform for writing your extensions, as you
570can take advantage of the regular enhancements to the foundational
571classes. It also prevents you from wasting time working on something
572which has already been done. A newly submitted task to do something
573complex such as talk to EJB engines, SOAP servers or just convert a text
574file to uppercase may be almost exactly what you need - so take it,
575enhance it and offer up the enhancements to the rest of the world. This
576is certainly better than starting work on your 'text case converter'
577task on Ant 0.8 in isolation, announcing its existence six months later
578and discovering that instead of adulation all you get are helpful
579pointers to the existing implementation. The final benefit of being
580involved with the process is that it makes it easier for your tasks to
581be added with the Ant CVS tree, bringing forward the date when Ant has
582taken on all the changes you needed to make to get your project to work.
583If that happens you can revert to an official Ant release, and get on
584with all the other crises.
585
586<p>
587You should also get on the <a href =
588"mailto:[email protected]">dev mailing list
589</a>, as it is where the other developers post their work, problems and
590experience. The volume can be quite high: 40+ messages a day, so
591consider routing it to an email address you don't use for much else. And
592don't make everyone on the team subscribe; it can be too much of a
593distraction.
594
595<a name="install">
596<h2>
597Installing with Ant.
598</h2>
599</a>
600Because Ant can read environment variables, copy, unzip and delete files
601and make java and OS calls, it can be used for simple installation
602tasks. For example, an installer for tomcat could extract the
603environment variable <tt>TOMCAT_HOME</tt>, stop tomcat running, and copy a war
604file to <tt>TOMCAT_HOME/webapps</tt>. It could even start tomcat again, but the
605build wouldn't complete until tomcat exited, which is probably not what
606was wanted.
607
608<p>
609The advantage of using Ant is firstly that the same install targets
610can be used from your local build files (via an <tt>ant</tt> invocation
611of the <tt>install.xml</tt> file), and secondly that a basic install target is
612quite easy to write. The disadvantages of this approach are that the
613destination must have an up to date version of Ant correctly
614pre-installed, and Ant doesn't allow you to handle failures well - and a
615good installer is all about handling when things go wrong, from files
616being in use to jar versions being different. This means that Ant is not
617suited for shrink wrapped software, but it does work for deployment and
618installation to your local servers.
619
620<p>
621One major build project I was involved in had an Ant install build file
622for the bluestone application server, which would shutdown all four
623instances of the app server on a single machine, copy the new version of
624the war file (with datestamp and buildstamp) to an archive directory,
625clean up the current deployed version of the war and then install the
626new version. Because bluestone restarted JVMs on demand, this script was
627all you needed for web service deployment. On the systems behind the
628firewall, we upped the ante in the deployment process by using the ftp
629task to copy out the war and build files, then the telnet task to
630remotely invoke the build file. The result was we had automated
631recompile and redeploy to local servers from inside our IDE (Jedit) or
632the command line, which was simply invaluable. Imagine pressing a button
633on your IDE toolbar to build, unit test, deploy and then functional test
634your webapp.
635
636<p>
637One extra trick I added later was a junit test case to run through the
638install check list. With tests to verify access permissions on network
639drives, approximate clock synchronisation between servers, DNS
640functionality, ability to spawn executables and all the other trouble
641spots, the install script could automatically do a system health test
642during install time and report problems. [The same tests could also be
643invoked from a JMX MBean, but that's another story].
644
645<p>
646So, Ant is not a substitute for a real installer tool, except in the
647special case of servers you control, but in that context it does let
648you integrate remote installation with your build.
649
650
651<a name="tips">
652<h2>
653Tips and Tricks</h2>
654</a>
655<dl>
656<dt><b>
657 get
658</b><dd>
659
660The <a href="manual/CoreTasks/get.html">get</a> task can fetch any URL, so be used
661to trigger remote server side code during the build process, from remote
662server restarts to sending SMS/pager messages to the developer
663cellphones.
664
665<dt><b>
666i18n
667</b><dd>
668
669Internationalisation is always trouble. Ant helps here with the <a href=
670"manual/OptionalTasks/native2ascii.html">native2ascii</a> task which can escape out all non
671ascii characters into unicode. You can use this to write java files
672which include strings (and indeed comments) in your own non-ASCII
673language and then use native2ascii to convert to ascii prior to feeding
674through javac. The rest of i18n and l12n is left to you...
675
676<dt><b>
677Use Property Files
678</b><dd>
679
680Use external property files to keep per-user settings out the build
681files - especially passwords. Property files can also be used to
682dynamically set a number of properties based on the value of a single
683property, simply by dynamically generating the property filename from the
684source property. They can also be used as a source of constants across
685multiple build files.
686
687<dt><b>
688Faster compiles with Jikes
689</b><dd>
690
691The <a href="http://jikes.sourceforge.net/">jikes compiler</a> is usually much
692faster than javac, does dependency checking and has better error
693messages (usually). Get it. Then set
694<tt>build.compiler</tt> to "jikes" for it to be used in your build files.
695Doing this explicitly in your build files is a bit dubious as it requires the
696whole team (and sub projects) to be using jikes too - something you can only
697control in small, closed source projects. But if you set
698<tt>ANT_OPTS&nbsp;=&nbsp;-Dbuild.compiler=jikes</tt>
699in your environment, then all your builds on your system will use
700Jikes automatically, while others can choose their own compiler, or let
701ant choose whichever is appropriate for the current version of Java.
702
703<dt><b>
704#include targets to simplify multi <tt>build.xml</tt> projects
705</b><dd>
706
707You can import XML files into a build file using the XML parser itself.
708This lets a multi-project development program share code through reference,
709rather than cut and paste re-use. It also lets one build up a file of
710standard tasks which can be reused over time. Because the import
711mechanism is at a level below which Ant is aware, treat it as
712equivalent to the #include mechanism of the 'legacy' languages C and
713C++.
714
715<p>
716There are two inclusion mechanisms, an ugly one for all parsers and a
717clean one. The ugly method is the only one that was available on Ant1.5 and
718earlier:-
719<pre>
720 &lt;!DOCTYPE project [
721 &lt;!ENTITY propertiesAndPaths SYSTEM &quot;propertiesAndPaths.xml&quot;&gt;
722 &lt;!ENTITY taskdefs SYSTEM &quot;taskdefs.xml&quot;&gt;
723 ]&gt;
724
725 &amp;propertiesAndPaths;
726 &amp;taskdefs;
727</pre>
728The cleaner method in Ant1.6 is the <tt>&lt;import&gt;</tt> task that imports
729whole build files into other projects. The entity inclusion example
730could <i>almost</i> be replaced by two import statements:-
731<pre>
732 &lt;import file="propertiesAndPaths.xml"&gt;
733 &lt;import file="taskdefs.xml"&gt;
734</pre>
735
736We say almost as top level declarations (properties and taskdefs)
737do not get inserted into the XML file exactly where the import statement
738goes, but added to the end of the file. This is because the import process
739takes place after the main build file is parsed, during execution, whereas
740XML entity expansion is handled during the parsing process.
741
742<p>
743The <tt>&lt;import&gt;</tt> task does powerful things, such as let you override targets,
744and use ant properties to name the location of the file to import. Consult the
745<a href="manual/CoreTasks/import.html">documentation</a> for the specifics of
746these features.
747
748<p>
749Before you go overboard with using XML inclusion, note that the
750<tt>ant</tt> task lets you call any target in any other build
751file - with all your property settings propagating down to that target.
752So you can actually have a suite of utility targets
753- "<tt>deploy-to-stack-a</tt>", "<tt>email-to-team</tt>", "<tt>cleanup-installation</tt>" which can
754be called from any of your main build files, perhaps with subtly changed
755parameters. Indeed, after a couple of projects you may be able to create
756a re-usable core build file which contains the core targets of a basic
757Java development project - compile, debug, deploy - which project specific
758build files call with their own settings. If you can achieve this then
759you are definitely making your way up the software maturity ladder. With
760a bit of work you may progress from being a SEI CMM Level 0 organisation
761&quot;Individual Heroics are not enough&quot; to SEI CMM Level 1, &quot;Projects only
762succeed due to individual heroics&quot;
763
764<p>
765NB, <tt>ant</tt> copies all your properties unless the
766<i>inheritall</i> attribute is set to false. Before that attribute
767existed you had to carefully name all property definitions in all build
768files to prevent unintentional overwriting of the invoked property by
769that of the caller, now you just have to remember to set
770<tt>inheritall="false"</tt> on all uses of the &lt;ant&gt; task.
771
772
773<dt><b>
774Implement complex Ant builds through XSL
775</b><dd>
776
777XSLT can be used to dynamically generate build.xml files from a source
778xml file, with the <a href="manual/CoreTasks/style.html">xslt</a> task controlling
779the transform. This is the current recommended strategy for creating
780complex build files dynamically. However, its use is still apparently
781quite rare - which means you will be on the bleeding edge of technology.
782
783
784<dt><b>
785Change the invocation scripts
786</b><dd>
787
788By writing your own invocation script - using the DOS, Unix or Perl
789script as a starting point - you can modify Ant's settings and behavior for an
790individual project. For example, you can use an alternate variable to
791<tt>ANT_HOME</tt> as the base, extend the classpath differently, or dynamically
792create a new command line property &quot;<tt>project.interfaces</tt>&quot; from all <tt>.jar</tt>
793files in an interfaces directory.
794
795<p>
796Having a custom invocation script which runs off a CVS controlled
797library tree under <tt>PROJECT_HOME</tt> also lets you control Ant versions
798across the team - developers can have other copies of Ant if they want,
799but the CVS tree always contains the jar set used to build your project.
800
801<p>
802You can also write wrapper scripts which invoke the existing Ant
803scripts. This is an easy way to extend them. The wrapper scripts can add
804extra definitions and name explicit targets, redefine <tt>ANT_HOME</tt> and
805generally make development easier. Note that &quot;ant&quot; in Windows is really
806&quot;ant.bat&quot;, so should be invoked from another batch file with a "CALL
807ant" statement - otherwise it never returns to your wrapper.
808
809
810<dt><b>
811Write all code so that it can be called from Ant
812</b><dd>
813This seems a bit strange and idealistic, but what it means is that you should
814write all your java code as if it may be called as a library at some point in
815future. So do not place calls to <tt>System.exit()</tt> deep in the code - if you
816want to exit a few functions in, raise an exception instead and have
817<tt>main()</tt> deal with it.
818
819<p>
820Moving one step further, consider proving an Ant Task interface to the
821code as a secondary, primary or even sole interface to the
822functionality. Ant actually makes a great bootloader for Java apps as it
823handles classpath setup, and you can re-use all the built in tasks for
824preamble and postamble work. Some projects, such as
825<a href="http://xdoclet.sf.net">XDoclet</a> only run under Ant, because
826that is the right place to be.
827
828<!-- <dt><b>
829Use Antidote as the invocation tool
830</b><dd>
831Even if you edit Ant files by hand, Antidote makes a good execution tool
832because it eliminates the startup time of the JVM, perhaps even some of
833the XML parsing delays.
834 -->
835<dt><b>
836Use the replace task to programmatic modify text files in your project.
837</b><dd>
838Imagine your project has some source files - BAT files, ASPX pages(!), anything
839which needs to be statically customised at compile time for particular
840installations, such driven from some properties of the project such as JVM options, or the URL
841to direct errors too. The replace task can be used to modify files, substituting text and creating
842versions customised for that build or destination. Of course, per-destination customisation
843should be delayed until installation, but if you are using Ant for the remote installation
844that suddenly becomes feasible.
845
846<dt><b>
847Use the mailing lists
848</b><dd>
849There are two
850<a href="http://ant.apache.org/mail.html">mailing lists</a>
851related to Ant, user and developer. Ant user is where <i>all</i>
852questions related to using Ant should go. Installation, syntax, code
853samples, etc - post your questions there or search the archives for
854whether the query has been posted and answered before. Ant-developer
855is where Ant development takes place - so it is <i>not</i> the place to
856post things like &quot;I get a compilation error when I build my project&quot; or
857&quot;how do I make a zip file&quot;. If you are actually extending Ant, on the other
858hand, it is the ideal place to ask questions about how to add new tasks, make
859changes to existing ones - and to post the results of your work, if you want them
860incorporated into the Ant source tree.
861</dl>
862
863<a name="puttingtogether">
864 <h2>
865 Putting it all together
866 </h2>
867</a>
868
869What does an Ant build process look like in this world? Assuming a
870single directory structure for simplicity, the build file
871should contain a number of top level targets
872<ul>
873<li>build - do an (incremental) build
874<li>test - run the junit tests
875<li>clean - clean out the output directories
876<li>deploy - ship the jars, wars, whatever to the execution system
877<li>publish - output the source and binaries to any distribution site
878<li>fetch - get the latest source from the cvs tree
879<li>docs/javadocs - do the documentation
880<li>all - clean, fetch, build, test, docs, deploy
881<li>main - the default build process (usually build or build &amp; test)
882</ul>
883Sub projects &quot;web&quot;, &quot;bean-1&quot;, &quot;bean-2&quot; can be given their own build
884files - <tt>web.xml</tt>, <tt>bean-1.xml</tt>, <tt>bean-2.xml</tt> - with the same entry points.
885Extra toplevel tasks related to databases, web site images and the like
886should be considered if they are part of the process.
887
888<p>
889Debug/release switching can be handled with separate initialisation
890targets called before the compile tasks which define the appropriate
891properties. Antcall is the trick here, as it allows you to have two paths
892of property initialisation in a build file.
893
894<p>
895Internal targets should be used to structure the process
896<ul>
897<li> init - initialise properties, extra-tasks, read in per-user
898property files.
899<li> init-release - initialise release properties
900<li> compile - do the actual compilation
901<li> link/jar - make the jars or equivalent
902<li> staging - any pre-deployment process in which the output is dropped
903 off then tested before being moved to the production site.
904</ul>
905
906The switching between debug and release can be done by making
907init-release conditional on a property, such as <tt>release.build</tt>
908being set :-
909
910<pre>&lt;target name=&quot;init-release&quot; if=&quot;release.build&quot;&gt;
911 &lt;property name=&quot;build.debuglevel&quot; value=&quot;lines,source&quot;/&gt;
912 &lt;/target&gt;
913</pre>
914
915You then have dependent targets, such as &quot;compile&quot;, depend on this
916conditional target; there the &quot;default&quot; properties are set, and then the
917property is actually used. Because Ant properties are <i>immutable</i>,
918if the release target was executed its settings will override the
919default values:
920
921<pre>&lt;target name=&quot;compile&quot; depends=&quot;init,init-release&quot;&gt;
922 &lt;property name=&quot;build.debuglevel&quot; value=&quot;lines,vars,source&quot;/&gt;
923 &lt;echo&gt;debug level=${build.debuglevel}&lt;/echo&gt;
924 &lt;javac destdir=&quot;${build.classes.dir}&quot;
925 debug=&quot;true&quot;
926 debuglevel=&quot;${build.debuglevel}&quot;
927 includeAntRuntime=&quot;false&quot;
928 srcdir=&quot;src&quot;&gt;
929 &lt;classpath refid=&quot;compile.classpath&quot;/&gt;
930 &lt;/javac&gt;
931 &lt;/target&gt;
932</pre>
933
934As a result, we now have a build where the release mode only includes
935the filename and line debug information (useful for bug reports), while
936the development system included variables too.
937<p>
938It is useful to define a project name property which can be echoed in
939the init task. This lets you work out which Ant file is breaking in a
940multi file build.
941
942<p>
943What goes in to the internal Ant tasks depends on your own projects. One
944very important tactic is &quot;keep path redefinition down through
945references&quot; - you can reuse paths by giving them an ID and then
946referring to them via the &quot;refid&quot; attribute you should only need to
947define a shared classpath once in the file; filesets can be reused
948similarly.
949
950<p>
951Once you have set up the directory structures, and defined the Ant tasks
952it is time to start coding. An early priority must be to set up the
953automated test process, as that not only helps ensures that the code
954works, it verifies that the build process is working.
955
956<p>
957And that's it. The build file shouldn't need changing as new source
958files get added, only when you want to change the deliverables or part
959of the build process. At some point you may want to massively
960restructure the entire build process, restructuring projects and the
961like, but even then the build file you have should act as a foundation
962for a split build file process -just pull out the common properties into
963a properties file all build files read in, keep the target names unified
964and keep going with the project. Restructuring the source code control
965system is often much harder work.
966
967<h2>The Limits of Ant</h2>
968
969Before you start adopting Ant as the sole mechanism for the build
970process, you need to be aware of what it doesn't do.
971<p>
972
973<h3>It's not a scripting language</h3>
974
975Ant lets you declare what you want done, with a bit of testing of the
976platform and class libraries first to enable some platform specific
977builds to take place. It does not let you specify how to handle things
978going wrong (a listener class can do that), or support complex
979conditional statements.
980
981<p>
982If your build needs to handle exceptions then look at the sound listener
983as a simple example of how to write your own listener class. Complex
984conditional statements can be handled by having something else do the
985tests and then build the appropriate Ant task. XSLT can be used for
986this.
987
988<h3>It's not Make</h3>
989
990Some of the features of make, specifically inference rules and
991dependency checking are not included in Ant. That's because they are
992&quot;different&quot; ways of doing a build. Make requires you to state
993dependencies and the build steps, Ant wants you to state tasks and the
994order between them, the tasks themselves can do dependency checking or
995not. A full java build using Jikes is so fast that dependency checking
996is relatively moot, while many of the other tasks (but not all), compare
997the timestamp of the source file with that of the destination file
998before acting.
999
1000<h3>It's not meant to be a nice language for humans</h3>
1001
1002XML isn't a nice representation of information for humans. It's a
1003reasonable representation for programs, and text editors and source code
1004management systems can all handle it nicely. But a complex Ant file can
1005get ugly because XML is a bit ugly, and a complex build is, well,
1006complicated. Use XML comments so that the file you wrote last month
1007still makes sense when you get back to it, and use Antidote to edit the
1008files if you prefer it.
1009
1010<h3>Big projects still get complicated fast</h3>
1011
1012Large software projects create their own complexity, with inter-dependent
1013libraries, long test cycles, hard deployment processes and a multitude of
1014people each working on their own bit of the solution. That's even before
1015the deadlines loom close, the integration problems become insurmountable,
1016weekends become indistinguishable from weekdays in terms of workload and
1017half the team stops talking to the other half. Ant may simplify the
1018build and test process, and can eliminate the full time &quot;makefile engineer&quot;
1019role, but that doesn't mean that someone can stop &quot;owning the build&quot;.
1020Being in charge of the build has to mean more than they type &quot;<tt>ant all</tt>&quot; on
1021their system, it means they need to set the standards of what build tools to
1022use, what the common targets, what property names and files should be
1023and generally oversee the sub projects build processes. On a small project,
1024you don't need to do that - but remember: small projects become big projects
1025when you aren't looking. If you start off with a little bit of process, then
1026you can scale it if needed. If you start with none, by the time you need
1027it will be too late.
1028
1029<h3>You still need all the other foundational bits of a software
1030project</h3>
1031
1032If you don't have an source code management system, you are going to end
1033up hosed. If you don't have everything under SCM, including web pages,
1034dependent jars, installation files, you are still going to end up hosed,
1035it's just a question of when it's going to happen.
1036CVS is effectively free and works well with Ant, but Sourcesafe, Perforce,
1037Clearcase and StarTeam also have Ant tasks. These tasks
1038let you have auto-incrementing build counters, and automated file
1039update processes.
1040
1041<p>
1042You also need some kind of change control process, to resist
1043uncontrolled feature creep. Bugzilla is a simple and low cost tool for
1044this, using Ant and a continuous test process enables a rapid evolution of code
1045to adapt to those changes which are inevitable.
1046
1047<h2>End piece</h2>
1048
1049Software development is meant to be fun. Being in the maelstrom of a
1050tight project with the stress of integration and trying to code
1051everything up for an insane deadline can be fun - it is certainly
1052exhilarating. Adding a bit of automation to the process may make things
1053less chaotic, and bit less entertaining, but it is a start to putting
1054you in control of your development process. You can still have fun, you
1055should just have less to worry about, a shorter build/test/deploy cycle
1056and more time to spend on feature creep or important things like skiing.
1057So get out there and have fun!
1058
1059<a name="reading">
1060<h2>Further Reading</h2>
1061</a>
1062<ul>
1063<li>
1064<a
1065href="http://www.martinfowler.com/articles/continuousIntegration.html">
1066<i>Continuous Integration</i></a>; Martin Fowler. <br>
1067A paper on using Ant within a software project
1068running a continuous integration/testing process.
1069<li><i> Refactoring</i>; Martin Fowler, ISBN: 0201485672 <br>
1070 Covers JUnit as well as tactics for making some headway with the mess of
1071 code you will soon have.
1072
1073<li><a href="http://manning.com/hatcher"><i>Java Development with
1074Ant</i></a>;
1075 Erik Hatcher and Steve Loughran.
1076
1077
1078<li>
1079<a href="http://www.iseran.com/Steve/papers/when_web_services_go_bad.html">
1080 <i>When Web Services Go Bad</i></a>; Steve Loughran.<br>
1081 One of the projects this paper is based on.
1082
1083
1084</ul>
1085
1086<a name="author">
1087<h3>About the Author</h3>
1088</a>
1089
1090Steve Loughran is a research scientist at a corporate R&amp;D lab,
1091currently on a sabbatical building production web services against
1092implausible deadlines for the fun of it. He is also a committer on
1093Apache Ant and Apache Axis, and co-author of
1094<a href="http://manning.com/hatcher"><i>Java Development with Ant</i></a>.
1095He thinks that if you liked this document you'll love that book because
1096it doesn't just explain Ant, it goes into processes, deployment and best practices
1097and other corners of stuff that really make Ant useful. (It would
1098have been easier to just rehash the manual, but that wouldn't have been
1099so useful or as much fun).
1100
1101<p>
1102For questions related to this document, use the Ant mailing list.
1103
1104<hr>
1105<p align="center">Copyright &copy; 2000-2005 The Apache Software Foundation. All rights
1106Reserved.</p>
1107</body>
1108</html>
Note: See TracBrowser for help on using the repository browser.