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