Return-Path: Delivered-To: apmail-ant-dev-archive@www.apache.org Received: (qmail 52732 invoked from network); 1 Sep 2006 21:42:38 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 1 Sep 2006 21:42:38 -0000 Received: (qmail 87184 invoked by uid 500); 1 Sep 2006 21:42:28 -0000 Delivered-To: apmail-ant-dev-archive@ant.apache.org Received: (qmail 86661 invoked by uid 500); 1 Sep 2006 21:42:24 -0000 Mailing-List: contact dev-help@ant.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Ant Developers List" Reply-To: "Ant Developers List" Delivered-To: mailing list dev@ant.apache.org Received: (qmail 86257 invoked by uid 500); 1 Sep 2006 21:42:21 -0000 Received: (qmail 86190 invoked by uid 99); 1 Sep 2006 21:42:21 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Sep 2006 14:42:20 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Sep 2006 14:42:12 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 885561A9820; Fri, 1 Sep 2006 14:41:52 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r439488 [3/13] - in /ant/site: ./ generated/ generated/ant2/ generated/antlibs/ generated/antlibs/antunit/ generated/antlibs/dotnet/ generated/antlibs/svn/ generated/images/ generated/projects/ generated/webtest/ Date: Fri, 01 Sep 2006 21:41:43 -0000 To: ant-cvs@apache.org From: bodewig@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060901214152.885561A9820@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: ant/site/generated/ant_in_anger.html URL: http://svn.apache.org/viewvc/ant/site/generated/ant_in_anger.html?rev=439488&view=auto ============================================================================== --- ant/site/generated/ant_in_anger.html (added) +++ ant/site/generated/ant_in_anger.html Fri Sep 1 14:41:40 2006 @@ -0,0 +1,1108 @@ + + + Ant in Anger + + + + +

Ant in Anger: +

+

+ Using Apache Ant in a Production Development System +

+ +

+Steve Loughran
+Last updated 2005-03-16 +

+ + + +

Introduction

+
+ +Apache Ant + can be an invaluable tool in a team development process - or it can +be yet another source of problems in that ongoing crises we call +development . This +document contains some strategies and tactics for making the most of +Ant. It is moderately frivolous in places, and lacks almost any actual +examples of Ant XML. The lack of examples is entirely deliberate - it +keeps document maintenance costs down. Most of the concepts covered +don't need the detail provided by XML representations, as it is the processes we +are concerned about, not the syntax. Finally, please be aware that the +comments here are only suggestions which need to be customised to meet +your own needs, not strict rules about what should and should not be +done. + +

+Firstly, here are some assumptions about the projects which this +document covers: +

    +
  • Pretty much pure Java, maybe with some legacy cruft on the edges. + +
  • Team efforts, usually with the petulant prima-donnas all us Java +programmers become once we realise how much in demand we are. + +
  • A fairly distributed development team - spread across locations and +maybe time zones. + +
  • Separate sub projects - from separate beans in a big +enterprise application to separate enterprise applications which need to +be vaguely aware of each other. + +
  • Significant mismatch between expectations and time available to +deliver. 'Last Week' is the ideal delivery date handed down from above, +late next century the date coming up from below. + +
  • Everyone is struggling to keep up with platform and tool evolution. + +
  • Extensive use of external libraries, both open and closed source. +
+ +What that all means is that there is no time to spend getting things +right, you don't have that tight control on how the rest of the team +works and the development process is often more one of chaos minimisation +than anything else. The role of Ant in such projects is to ensure that +the build, test and deploy processes run smoothly, leaving you with all +the other problems. + + +

Core Practices

+
+

+Clarify what you want Ant to do

+ +Ant is not a silver bullet. It is just another rusty bullet in the armory of +development tools available at your disposal. Its primary purpose is to +accelerate the construction and deployment of Java projects. You could certainly +extend Ant to do anything Java makes possible: it is easy to imagine writing an +image processing task to help in web site deployment by shrinking and +recompressing jpeg files, for example. But that would be pushing the boundary of +what Ant is really intended to do - so should be considered with care. + +

+Ant is also a great adjunct to an IDE; a way of doing all the housekeeping of +deployment and for clean, automated builds. But a good modern IDE is a +productivity tool in its own right - one you should continue to use. Ant +just lets you give the teams somewhat more freedom in IDE choice - "you can +use whatever you want in development, but Ant for the deployment +builds" Now that many modern open source and commercial IDEs +include Ant support (including jEdit, Forte, Eclipse and IDEA), +developers can use a great IDE, with Ant providing a rigorous and portable +build process integrated into the tool. + +

+Define standard targets +

+ +When you have multiple sub projects, define a standard set of targets. +Projects with a split between interface and implementation jar files +could consider impl and intf targets - with separate +debug-impl and debug-intf targets for the debug version. +And of course, the ubiquitous clean target. + +

+ +With standard target names, it is easy to build encompassing Ant build +files which just hand off the work to the classes below using the +ant +task. For example. the clean target could be handed down to the intf and +impl subdirectories from a parent directory + +

<target name="clean"  depends="clean-intf, clean-impl">
+</target>
+
+<target name="clean-intf" >
+    <ant dir="intf" target="clean" />
+</target>
+
+<target name="clean-impl">
+    <ant dir="impl" target="clean" />
+</target>  
+ +If you give targets a description tag, then calling ant +-projecthelp will list all tasks with their description as 'main targets', and +all tasks without a description as subtargets. Describing all your +entry points is therefore very useful, even before a project becomes big and complicated. + +

+ Extend Ant through new tasks +

+ +If Ant does not do what you want, you can use the +exec and +java tasks or +inline scripting to extend it. In a +project with many build.xml files, you soon find that having a single +central place for implementing the functionality keeps maintenance +overhead down. Implementing task extensions through Java code seems +extra effort at first, but gives extra benefits:- + +
    +
  • Cross platform support can be added later without changing any +build.xml files
  • + +
  • The code can be submitted to the Ant project itself, for other +people to use and maintain
  • + +
  • It keeps the build files simpler
  • +
+ +In a way, it is this decoupling of functionality, "the tasks", from +the declaration of use, "the build file", that has helped Ant succeed. +If you have to get something complex done in Make or an IDE, you have a +hairy makefile that everyone is scared of, or an IDE configuration that +is invariably very brittle. But an Ant task is reusable and shareable +among all Ant users. Many of the core and optional tasks in Ant today, +tasks you do or will come to depend on, were written by people trying to +solve their own pressing problems. + +

+Embrace Automated Testing +

+ +(alternatively "recriminate early, recriminate often") +

+Ant lets you call JUnit +tasks, which unit test the code your team has written. Automated testing +may seem like extra work at first, but JUnit makes writing unit tests so +easy that you have almost no reason not to. Invest the time in learning +how to use JUnit, write the test cases, and integrate them in a 'test' +target from Ant so that your daily or hourly team build can have the +tests applied automatically. One of the free to download chapters of +Java Development with Ant +shows you how to use JUnit from inside Ant. + +

+Once you add a way to fetch code from the SCM system, either as an Ant +task, in some shell script or batch file or via some continuous +integration tool. the integration test code can be a pure Ant task run +on any box dedicated to the task. This is ideal for verifying that the +build and unit tests work on different targets from the usual +development machines. For example, a Win95/Java1.1 combination could be +used even though no developer would willingly use that configuration +given the choice. + +

+System tests are harder to automate than unit tests, but if you can +write java code to stress large portions of the system - even if the code +can not run as JUnit tasks - then the java +task can be used to invoke them. It is best to specify that you want a +new JVM for these tests, so that a significant crash does not break the +full build. The Junit extensions such as +HttpUnit for web pages, and +Cactus for J2EE and servlet +testing help to expand the testing framework. To test properly you will still +need to invest a lot of effort in getting these to work with your project, and +deriving great unit, system and regression tests - but your customers will love +you for shipping software that works. + +

Learn to Use and love the add-ons to Ant

+The Ant distribution is not the limit of the Ant universe, it is only +the beginning. Look at the + +External Tools and Tasks page + for an up to date list. Here are some of them that . + +
    +
  • +Checkstyle
    +This tool audits your code and generates HTML reports of wherever any +style rule gets broken. Nobody can hide from the code police now! tip: +start using this early, so there's less to correct.
  • +
  • +Ant-contrib
    +This sourceforge project contains helper tasks that are kept separate +from core Ant for ideological purity; the foreach and trycatch tasks in +particular. These give you iteration and extra error handling. Also on +the site is the <cc> task suite, that compile and link native code +on a variety of platforms.
  • +
  • +XDoclet +XDoclet adds attributed oriented programming to Java. By adding javadoc +tags to your code you can have XDoclet automatically generate web.xml +descriptors, taglib descriptors, EJB interfaces, JMX interface classes, +Castor XML/SQL bindings, and many more. The key here is that all those +fiddly little XML files you need to create, and those interfaces EJB and +JMX requires to implement, all can be autogenerated from your Java +code with a few helper attributes. This reduces +errors and means you can change your code and have the rest of the app +take its cue from the source. Never do EJB, JMX or webapps without it! +
  • +
+ + +

+Cross Platform Ant +

+
+Ant is the best foundation for cross platform Java development and +testing to date. But if you are not paying attention, it is possible to +produce build files which only work on one platform - or indeed, one +single workstation. + +

+The common barriers to cross-platform Ant are the use of command line +tools (exec tasks) which are not portable, path issues, and hard coding +in the location of things. + +

Command Line apps: Exec / + Apply

+ +The trouble with external invocation is that not all functions are found +cross platform, and those that are often have different names - DOS +descendants often expect .exe or .bat at the end of files. That can be +bad if you explicitly include the extension in the naming of the command +(don't!), good when it lets you keep the unix and DOS versions of an +executable in the same bin directory of the project without name +clashes arising. + +

+Both the command line invocation tasks let you specify which platform +you want the code to run on, so you could write different tasks for each +platform you are targeting. Alternatively, the platform differences +could be handled inside some external code which Ant calls. This can be +some compiled down java in a new task, or an external script file. + +

Cross platform paths

+ +Unix paths use forward slashes between directories and a colon to +split entries. Thus +"/bin/java/lib/xerces.jar:/bin/java/lib/ant.jar" is +a path in unix. In Windows the path must use semicolon separators, +colons being used to specify disk drives, and backslash separators +"c:\bin\java\lib\xerces.jar;c:\bin\java\lib\ant.jar". +

+This difference between platforms (indeed, the whole java classpath +paradigm) can cause hours of fun. + +

+Ant reduces path problems; but does not eliminate them entirely. You +need to put in some effort too. The rules for handling path names are +that 'DOS-like pathnames are handled', 'Unix like paths are handled'. +Disk drives -'C:'- are handled on DOS-based boxes, but placing them in +the build.xml file ruins all chances of portability. Relative file paths +are much more portable. Semicolons work as path separators - a fact which +is useful if your Ant invocation wrapper includes a list of jars as a +defined property in the command line. In the build files you may find it +better to build a classpath by listing individual files (using location= +attributes), or by including a fileset of *.jar in the classpath +definition. +

+There is also the PathConvert task which +can put a fully resolved path into a property. Why do that? Because then +you can use that path in other ways - such as pass it as a parameter to +some application you are calling, or use the replace task to patch it +into a localised shell script or batch file. +

+Note that DOS descended file systems are case insensitive (apart from +the obscure aberration of the WinNT POSIX subsystem run against NTFS), +and that Windows pretends that all file extensions with four or more +letters are also three letter extensions (try DELETE *.jav in your java +directories to see a disastrous example of this). + +

+Ant's policy on case sensitivity is whatever the underlying file system +implements, and its handling of file extensions is that *.jav does not +find any .java files. The Java compiler is of course case sensitive - you can +not have a class 'ExampleThree' implemented in "examplethree.java". + +

+Some tasks only work on one platform - +Chmod being a classic example. These tasks usually result in just a +warning message on an unsupported platform - the rest of the target's +tasks will still be called. Other tasks degrade their functionality on +platforms or Java versions. In particular, any task which adjusts the +timestamp of files can not do so properly on Java 1.1. Tasks which can +do that - Get, Touch and +Unjar/Unwar/Unzip for example, degrade their functionality on +Java1.1, usually resorting to the current timestamp instead. + +

+Finally, Perl makes a good place to wrap up Java invocations cross +platform, rather than batch files. It is included in most Unix +distributions, and is a simple download for Win32 platforms from +ActiveState. A Perl file with .pl extension, the usual Unix +path to perl on the line 1 comment and marked as executable can be run +on Windows, OS/2 and Unix and hence called from Ant without issues. The +perl code can be left to resolve its own platform issues. Don't forget to +set the line endings of the file to the appropriate platform when you +redistribute Perl code; fixCRLF +can do that for you. + + +

Team Development Processes

+ +Even if each team member is allowed their choice of IDE/editor, or even +OS, you need to set a baseline of functionality on each box. In +particular, the JDKs and jars need to be in perfect sync. Ideally pick +the latest stable Java/JDK version available on all developer/target +systems and stick with it for a while. Consider assigning one person to +be the contact point for all tools coming in - particularly open source +tools when a new build is available on a nightly basis. Unless needed, +these tools should only really be updated monthly, or when a formal +release is made. + +

+Another good tactic is to use a unified directory tree, and add on extra +tools inside that tree. All references can be made relative to the tree. +If team members are expected to add a directory in the project to their +path, then command line tools can be included there - including those +invoked by Ant exec tasks. Put everything under source code control and +you have a one stop shop for getting a build/execute environment purely +from CVS or your equivalent. + + +

Deploying with Ant

+ +One big difference between Ant and older tools such as Make is that the +processes for deploying Java to remote sites are reasonably well +evolved in Ant. That is because we all have to do it these days, so +many people have put in the effort to make the tasks easier. +

+Ant can Jar, Tar or Zip files for deployment, while the +War task extends the jar task +for better servlet deployment. +Jlink is a +jar generation file which lets you merge multiple sub jars. This is +ideal for a build process in which separate jars are generated by sub +projects, yet the final output is a merged jar. Cab can be used on Win32 boxes to +build a cab file which is useful if you still have to target IE deployment. + +

+The ftp task lets you move stuff up to a +server. Beware of putting the ftp password in the build file - a property +file with tight access control is slightly better. The FixCRLF task is often a useful interim step if +you need to to adjust the line endings of files. A +WebDav task has long been discussed, which would provide a more secure +upload to web servers, but it is still in the todo list. Rumour has it +that there is such a task in the jakarta-slide libraries. With MacOS X, +Linux and Windows XP all supporting WebDAV file systems, you may even be able +to use copy to deploy +though a firewall. + +

+EJB deployment is aided by the ejb tasks, +while the +serverdeploy +suite can deploy to multiple servers. The popularity of Ant has +encouraged vendors to produce their own deployment tasks which they +redistribute with their servers. For example, the Tomcat4.1 installation +includes tasks to deploy, undeploy and reload web applications. + +

+Finally, there are of course the fallbacks of just copying files to a +destination using Copy and Copydir , or just sending them to a person or +process using Mail or the attachment +aware MimeMail. +In one project our team even used Ant to build CD images through a build followed +by a long set of Copy tasks, which worked surprisingly well, certainly +easier than when we mailed them to the free email service on +myrealbox.com, then pulled them down from the far end's web browser, which we +were running over WinNT remote desktop connection, that being tunneled +through SSH. + + +

Directory Structures

+ + +How you structure your directory tree is very dependent upon the +project. Here are some directory layout patterns which can be used as +starting points. All the jakarta projects follow a roughly similar +style, which makes it easy to navigate around one from one project to +another, and easy to clean up when desired. + +

Simple Project

+ +The project contains sub directories + + + + + + + + + + + + + + + + + + + + + + + + + + +
bin + common binaries, scripts - put this on the path. +
build + This is the tree for building; Ant creates it and can empty it + in the 'clean' project. +
dist + Distribution outputs go in here; the directory is created in Ant + and clean empties it out +
doc + Hand crafted documentation +
lib + Imported Java libraries go in to this directory +
src + source goes in under this tree in a hierarchy which matches + the package names. The dependency rules of <javac> requires this. +
+ +The bin, lib, doc and src directories should be under source code control. +Slight variations include an extra tree of content to be included in the +distribution jars - inf files, images, etc. These can go under source +too, with a metadata directory for web.xml and similar +manifests, and a web folder for web content - JSP, html, images +and so on. Keeping the content in this folder (or sub hierarchy) +together makes it easier to test links before deployment. The actual +production of a deployment image, such as a war file, can be left to the +appropriate Ant task: there is no need to completely model your source tree +upon the deployment hierarchy. +

+Javadoc output can be +directed to a doc/ folder beneath build/, or to doc/javadoc. + +

Interface and Implementation split

+ +If the interface is split from the implementation code then this can be +supported with minor changes just by having a separate build path for +the interface directory - or better still just in the jar construction: +one jar for interface and one jar for implementation. + +

Loosely Coupled Sub Projects

+ +In the loosely coupled approach multiple projects can have their own +copy of the tree, with their own source code access rights. +One difference to consider is only having one instance of the bin and +lib directories across all projects. This is sometimes good - it helps +keep copies of xerces.jar in sync, and sometimes bad - it can update +foundational jar files before unit testing is complete. + +

+To still have a single build across the sub projects, use parent +build.xml files which call down into the sub projects. +

+This style works well if different teams have different code +access/commitment rights. The risk is that by giving extra leeway to the +sub projects, you can end up with incompatible source, libraries, build +processes and just increase your workload and integration grief all round. +

+The only way to retain control over a fairly loosely integrated +collection of projects is to have a fully automated build +and test process which verifies that everything is still compatible. Sam +Ruby runs one for all the apache java libraries and emails everyone when +something breaks; your own project may be able to make use of +Cruise Control for +an automated, continuous, background build process. + +

Integrated sub projects

+ +Tightly coupled projects have all the source in the same tree; different +projects own different subdirectories. Build files can be moved down to +those subdirectories (say src/com/iseran/core and src/com/iseran/extras), +or kept at the top - with independent build files named core.xml and +extras.xml. + +

+This project style works well if everyone trusts each other and the +sub projects are not too huge or complex. The risk is that a split to a +more loosely coupled design will become a requirement as the projects +progress - but by the time this is realised schedule pressure and +intertwined build files make executing the split well nigh impossible. +If that happens then just keep with it until there is the time to +refactor the project directory structures. + + +

+ Ant Update Policies +

+ + +Once you start using Ant, you should have a policy on when and how the +team updates their copies. A simple policy is "every official release +after whatever high stress milestone has pushed all unimportant tasks +(like sleep and seeing daylight) on the back burner". This insulates you +from the changes and occasional instabilities that Ant goes through +during development. Its main disadvantage is that it isolates you from +the new tasks and features that Ant is constantly adding. + +

+Often an update will require changes to the build.xml files. Most +changes are intended to be backwards compatible, but sometimes an +incompatible change turns out to be +necessary. That is why doing the update in the lull after a big +milestone is important. It is also why including ant.jar and related +files in the CVS tree helps ensure that old versions of your software +can be still be built. + +

+The most aggressive strategy is to get a weekly or daily snapshot of the +ant source, build it up and use it. This forces you to tweak the +build.xml files more regularly, as new tasks and attributes can take +while to stabilise. You really have to want the new features, enjoy +gratuitous extra work or take pleasure in upsetting your colleagues to +take this approach. + +

+Once you start extending Ant with new tasks, it suddenly becomes much +more tempting to pull down regular builds. The most recent Ant builds +are invariably the best platform for writing your extensions, as you +can take advantage of the regular enhancements to the foundational +classes. It also prevents you from wasting time working on something +which has already been done. A newly submitted task to do something +complex such as talk to EJB engines, SOAP servers or just convert a text +file to uppercase may be almost exactly what you need - so take it, +enhance it and offer up the enhancements to the rest of the world. This +is certainly better than starting work on your 'text case converter' +task on Ant 0.8 in isolation, announcing its existence six months later +and discovering that instead of adulation all you get are helpful +pointers to the existing implementation. The final benefit of being +involved with the process is that it makes it easier for your tasks to +be added with the Ant CVS tree, bringing forward the date when Ant has +taken on all the changes you needed to make to get your project to work. +If that happens you can revert to an official Ant release, and get on +with all the other crises. + +

+You should also get on the dev mailing list +, as it is where the other developers post their work, problems and +experience. The volume can be quite high: 40+ messages a day, so +consider routing it to an email address you don't use for much else. And +don't make everyone on the team subscribe; it can be too much of a +distraction. + + +

+Installing with Ant. +

+ +Because Ant can read environment variables, copy, unzip and delete files +and make java and OS calls, it can be used for simple installation +tasks. For example, an installer for tomcat could extract the +environment variable TOMCAT_HOME, stop tomcat running, and copy a war +file to TOMCAT_HOME/webapps. It could even start tomcat again, but the +build wouldn't complete until tomcat exited, which is probably not what +was wanted. + +

+The advantage of using Ant is firstly that the same install targets +can be used from your local build files (via an ant invocation +of the install.xml file), and secondly that a basic install target is +quite easy to write. The disadvantages of this approach are that the +destination must have an up to date version of Ant correctly +pre-installed, and Ant doesn't allow you to handle failures well - and a +good installer is all about handling when things go wrong, from files +being in use to jar versions being different. This means that Ant is not +suited for shrink wrapped software, but it does work for deployment and +installation to your local servers. + +

+One major build project I was involved in had an Ant install build file +for the bluestone application server, which would shutdown all four +instances of the app server on a single machine, copy the new version of +the war file (with datestamp and buildstamp) to an archive directory, +clean up the current deployed version of the war and then install the +new version. Because bluestone restarted JVMs on demand, this script was +all you needed for web service deployment. On the systems behind the +firewall, we upped the ante in the deployment process by using the ftp +task to copy out the war and build files, then the telnet task to +remotely invoke the build file. The result was we had automated +recompile and redeploy to local servers from inside our IDE (Jedit) or +the command line, which was simply invaluable. Imagine pressing a button +on your IDE toolbar to build, unit test, deploy and then functional test +your webapp. + +

+One extra trick I added later was a junit test case to run through the +install check list. With tests to verify access permissions on network +drives, approximate clock synchronisation between servers, DNS +functionality, ability to spawn executables and all the other trouble +spots, the install script could automatically do a system health test +during install time and report problems. [The same tests could also be +invoked from a JMX MBean, but that's another story]. + +

+So, Ant is not a substitute for a real installer tool, except in the +special case of servers you control, but in that context it does let +you integrate remote installation with your build. + + + +

+Tips and Tricks

+ +
+
+ get +
+ +The get task can fetch any URL, so be used +to trigger remote server side code during the build process, from remote +server restarts to sending SMS/pager messages to the developer +cellphones. + +
+i18n +
+ +Internationalisation is always trouble. Ant helps here with the native2ascii task which can escape out all non +ascii characters into unicode. You can use this to write java files +which include strings (and indeed comments) in your own non-ASCII +language and then use native2ascii to convert to ascii prior to feeding +through javac. The rest of i18n and l12n is left to you... + +
+Use Property Files +
+ +Use external property files to keep per-user settings out the build +files - especially passwords. Property files can also be used to +dynamically set a number of properties based on the value of a single +property, simply by dynamically generating the property filename from the +source property. They can also be used as a source of constants across +multiple build files. + +
+Faster compiles with Jikes +
+ +The jikes compiler is usually much +faster than javac, does dependency checking and has better error +messages (usually). Get it. Then set +build.compiler to "jikes" for it to be used in your build files. +Doing this explicitly in your build files is a bit dubious as it requires the +whole team (and sub projects) to be using jikes too - something you can only +control in small, closed source projects. But if you set +ANT_OPTS = -Dbuild.compiler=jikes +in your environment, then all your builds on your system will use +Jikes automatically, while others can choose their own compiler, or let +ant choose whichever is appropriate for the current version of Java. + +
+#include targets to simplify multi build.xml projects +
+ +You can import XML files into a build file using the XML parser itself. +This lets a multi-project development program share code through reference, +rather than cut and paste re-use. It also lets one build up a file of +standard tasks which can be reused over time. Because the import +mechanism is at a level below which Ant is aware, treat it as +equivalent to the #include mechanism of the 'legacy' languages C and +C++. + +

+There are two inclusion mechanisms, an ugly one for all parsers and a +clean one. The ugly method is the only one that was available on Ant1.5 and +earlier:- +

+    <!DOCTYPE project [
+      <!ENTITY propertiesAndPaths SYSTEM "propertiesAndPaths.xml">
+      <!ENTITY taskdefs SYSTEM "taskdefs.xml">
+    ]>  
+    
+        &propertiesAndPaths;
+        &taskdefs;
+
+The cleaner method in Ant1.6 is the <import> task that imports +whole build files into other projects. The entity inclusion example +could almost be replaced by two import statements:- +
+ <import file="propertiesAndPaths.xml">
+ <import file="taskdefs.xml">
+
+ +We say almost as top level declarations (properties and taskdefs) +do not get inserted into the XML file exactly where the import statement +goes, but added to the end of the file. This is because the import process +takes place after the main build file is parsed, during execution, whereas +XML entity expansion is handled during the parsing process. + +

+The <import> task does powerful things, such as let you override targets, +and use ant properties to name the location of the file to import. Consult the +documentation for the specifics of +these features. + +

+Before you go overboard with using XML inclusion, note that the +ant task lets you call any target in any other build +file - with all your property settings propagating down to that target. +So you can actually have a suite of utility targets +- "deploy-to-stack-a", "email-to-team", "cleanup-installation" which can +be called from any of your main build files, perhaps with subtly changed +parameters. Indeed, after a couple of projects you may be able to create +a re-usable core build file which contains the core targets of a basic +Java development project - compile, debug, deploy - which project specific +build files call with their own settings. If you can achieve this then +you are definitely making your way up the software maturity ladder. With +a bit of work you may progress from being a SEI CMM Level 0 organisation +"Individual Heroics are not enough" to SEI CMM Level 1, "Projects only +succeed due to individual heroics" + +

+NB, ant copies all your properties unless the +inheritall attribute is set to false. Before that attribute +existed you had to carefully name all property definitions in all build +files to prevent unintentional overwriting of the invoked property by +that of the caller, now you just have to remember to set +inheritall="false" on all uses of the <ant> task. + + +

+Implement complex Ant builds through XSL +
+ +XSLT can be used to dynamically generate build.xml files from a source +xml file, with the xslt task controlling +the transform. This is the current recommended strategy for creating +complex build files dynamically. However, its use is still apparently +quite rare - which means you will be on the bleeding edge of technology. + + +
+Change the invocation scripts +
+ +By writing your own invocation script - using the DOS, Unix or Perl +script as a starting point - you can modify Ant's settings and behavior for an +individual project. For example, you can use an alternate variable to +ANT_HOME as the base, extend the classpath differently, or dynamically +create a new command line property "project.interfaces" from all .jar +files in an interfaces directory. + +

+Having a custom invocation script which runs off a CVS controlled +library tree under PROJECT_HOME also lets you control Ant versions +across the team - developers can have other copies of Ant if they want, +but the CVS tree always contains the jar set used to build your project. + +

+You can also write wrapper scripts which invoke the existing Ant +scripts. This is an easy way to extend them. The wrapper scripts can add +extra definitions and name explicit targets, redefine ANT_HOME and +generally make development easier. Note that "ant" in Windows is really +"ant.bat", so should be invoked from another batch file with a "CALL +ant" statement - otherwise it never returns to your wrapper. + + +

+Write all code so that it can be called from Ant +
+This seems a bit strange and idealistic, but what it means is that you should +write all your java code as if it may be called as a library at some point in +future. So do not place calls to System.exit() deep in the code - if you +want to exit a few functions in, raise an exception instead and have +main() deal with it. + +

+Moving one step further, consider proving an Ant Task interface to the +code as a secondary, primary or even sole interface to the +functionality. Ant actually makes a great bootloader for Java apps as it +handles classpath setup, and you can re-use all the built in tasks for +preamble and postamble work. Some projects, such as +XDoclet only run under Ant, because +that is the right place to be. + + +

+Use the replace task to programmatic modify text files in your project. +
+Imagine your project has some source files - BAT files, ASPX pages(!), anything +which needs to be statically customised at compile time for particular +installations, such driven from some properties of the project such as JVM options, or the URL +to direct errors too. The replace task can be used to modify files, substituting text and creating +versions customised for that build or destination. Of course, per-destination customisation +should be delayed until installation, but if you are using Ant for the remote installation +that suddenly becomes feasible. + +
+Use the mailing lists +
+There are two +mailing lists +related to Ant, user and developer. Ant user is where all +questions related to using Ant should go. Installation, syntax, code +samples, etc - post your questions there or search the archives for +whether the query has been posted and answered before. Ant-developer +is where Ant development takes place - so it is not the place to +post things like "I get a compilation error when I build my project" or +"how do I make a zip file". If you are actually extending Ant, on the other +hand, it is the ideal place to ask questions about how to add new tasks, make +changes to existing ones - and to post the results of your work, if you want them +incorporated into the Ant source tree. +
+ + +

+ Putting it all together +

+
+ +What does an Ant build process look like in this world? Assuming a +single directory structure for simplicity, the build file +should contain a number of top level targets +
    +
  • build - do an (incremental) build +
  • test - run the junit tests +
  • clean - clean out the output directories +
  • deploy - ship the jars, wars, whatever to the execution system +
  • publish - output the source and binaries to any distribution site +
  • fetch - get the latest source from the cvs tree +
  • docs/javadocs - do the documentation +
  • all - clean, fetch, build, test, docs, deploy +
  • main - the default build process (usually build or build & test) +
+Sub projects "web", "bean-1", "bean-2" can be given their own build +files - web.xml, bean-1.xml, bean-2.xml - with the same entry points. +Extra toplevel tasks related to databases, web site images and the like +should be considered if they are part of the process. + +

+Debug/release switching can be handled with separate initialisation +targets called before the compile tasks which define the appropriate +properties. Antcall is the trick here, as it allows you to have two paths +of property initialisation in a build file. + +

+Internal targets should be used to structure the process +

    +
  • init - initialise properties, extra-tasks, read in per-user +property files. +
  • init-release - initialise release properties +
  • compile - do the actual compilation +
  • link/jar - make the jars or equivalent +
  • staging - any pre-deployment process in which the output is dropped + off then tested before being moved to the production site. +
+ +The switching between debug and release can be done by making +init-release conditional on a property, such as release.build +being set :- + +
<target name="init-release" if="release.build">
+    <property name="build.debuglevel" value="lines,source"/>    
+  </target>
+
+ +You then have dependent targets, such as "compile", depend on this +conditional target; there the "default" properties are set, and then the +property is actually used. Because Ant properties are immutable, +if the release target was executed its settings will override the +default values: + +
<target name="compile" depends="init,init-release">
+    <property name="build.debuglevel" value="lines,vars,source"/> 
+    <echo>debug level=${build.debuglevel}</echo>
+    <javac destdir="${build.classes.dir}"
+       debug="true"
+       debuglevel="${build.debuglevel}"
+       includeAntRuntime="false"
+       srcdir="src">
+      <classpath refid="compile.classpath"/>
+    </javac>
+  </target>
+
+ +As a result, we now have a build where the release mode only includes +the filename and line debug information (useful for bug reports), while +the development system included variables too. +

+It is useful to define a project name property which can be echoed in +the init task. This lets you work out which Ant file is breaking in a +multi file build. + +

+What goes in to the internal Ant tasks depends on your own projects. One +very important tactic is "keep path redefinition down through +references" - you can reuse paths by giving them an ID and then +referring to them via the "refid" attribute you should only need to +define a shared classpath once in the file; filesets can be reused +similarly. + +

+Once you have set up the directory structures, and defined the Ant tasks +it is time to start coding. An early priority must be to set up the +automated test process, as that not only helps ensures that the code +works, it verifies that the build process is working. + +

+And that's it. The build file shouldn't need changing as new source +files get added, only when you want to change the deliverables or part +of the build process. At some point you may want to massively +restructure the entire build process, restructuring projects and the +like, but even then the build file you have should act as a foundation +for a split build file process -just pull out the common properties into +a properties file all build files read in, keep the target names unified +and keep going with the project. Restructuring the source code control +system is often much harder work. + +

The Limits of Ant

+ +Before you start adopting Ant as the sole mechanism for the build +process, you need to be aware of what it doesn't do. +

+ +

It's not a scripting language

+ +Ant lets you declare what you want done, with a bit of testing of the +platform and class libraries first to enable some platform specific +builds to take place. It does not let you specify how to handle things +going wrong (a listener class can do that), or support complex +conditional statements. + +

+If your build needs to handle exceptions then look at the sound listener +as a simple example of how to write your own listener class. Complex +conditional statements can be handled by having something else do the +tests and then build the appropriate Ant task. XSLT can be used for +this. + +

It's not Make

+ +Some of the features of make, specifically inference rules and +dependency checking are not included in Ant. That's because they are +"different" ways of doing a build. Make requires you to state +dependencies and the build steps, Ant wants you to state tasks and the +order between them, the tasks themselves can do dependency checking or +not. A full java build using Jikes is so fast that dependency checking +is relatively moot, while many of the other tasks (but not all), compare +the timestamp of the source file with that of the destination file +before acting. + +

It's not meant to be a nice language for humans

+ +XML isn't a nice representation of information for humans. It's a +reasonable representation for programs, and text editors and source code +management systems can all handle it nicely. But a complex Ant file can +get ugly because XML is a bit ugly, and a complex build is, well, +complicated. Use XML comments so that the file you wrote last month +still makes sense when you get back to it, and use Antidote to edit the +files if you prefer it. + +

Big projects still get complicated fast

+ +Large software projects create their own complexity, with inter-dependent +libraries, long test cycles, hard deployment processes and a multitude of +people each working on their own bit of the solution. That's even before +the deadlines loom close, the integration problems become insurmountable, +weekends become indistinguishable from weekdays in terms of workload and +half the team stops talking to the other half. Ant may simplify the +build and test process, and can eliminate the full time "makefile engineer" +role, but that doesn't mean that someone can stop "owning the build". +Being in charge of the build has to mean more than they type "ant all" on +their system, it means they need to set the standards of what build tools to +use, what the common targets, what property names and files should be +and generally oversee the sub projects build processes. On a small project, +you don't need to do that - but remember: small projects become big projects +when you aren't looking. If you start off with a little bit of process, then +you can scale it if needed. If you start with none, by the time you need +it will be too late. + +

You still need all the other foundational bits of a software +project

+ +If you don't have an source code management system, you are going to end +up hosed. If you don't have everything under SCM, including web pages, +dependent jars, installation files, you are still going to end up hosed, +it's just a question of when it's going to happen. +CVS is effectively free and works well with Ant, but Sourcesafe, Perforce, +Clearcase and StarTeam also have Ant tasks. These tasks +let you have auto-incrementing build counters, and automated file +update processes. + +

+You also need some kind of change control process, to resist +uncontrolled feature creep. Bugzilla is a simple and low cost tool for +this, using Ant and a continuous test process enables a rapid evolution of code +to adapt to those changes which are inevitable. + +

End piece

+ +Software development is meant to be fun. Being in the maelstrom of a +tight project with the stress of integration and trying to code +everything up for an insane deadline can be fun - it is certainly +exhilarating. Adding a bit of automation to the process may make things +less chaotic, and bit less entertaining, but it is a start to putting +you in control of your development process. You can still have fun, you +should just have less to worry about, a shorter build/test/deploy cycle +and more time to spend on feature creep or important things like skiing. +So get out there and have fun! + + +

Further Reading

+
+
    +
  • + +Continuous Integration; Martin Fowler.
    +A paper on using Ant within a software project +running a continuous integration/testing process. +
  • Refactoring; Martin Fowler, ISBN: 0201485672
    + Covers JUnit as well as tactics for making some headway with the mess of + code you will soon have. + +
  • Java Development with +Ant; + Erik Hatcher and Steve Loughran. + + +
  • + + When Web Services Go Bad; Steve Loughran.
    + One of the projects this paper is based on. + + +
+ + +

About the Author

+
+ +Steve Loughran is a research scientist at a corporate R&D lab, +currently on a sabbatical building production web services against +implausible deadlines for the fun of it. He is also a committer on +Apache Ant and Apache Axis, and co-author of +Java Development with Ant. +He thinks that if you liked this document you'll love that book because +it doesn't just explain Ant, it goes into processes, deployment and best practices +and other corners of stuff that really make Ant useful. (It would +have been easier to just rehash the manual, but that wouldn't have been +so useful or as much fun). + +

+For questions related to this document, use the Ant mailing list. + +


+

Copyright © 2000-2005 The Apache Software Foundation. All rights +Reserved.

+ + Propchange: ant/site/generated/ant_in_anger.html ------------------------------------------------------------------------------ svn:eol-style = native Added: ant/site/generated/ant_task_guidelines.html URL: http://svn.apache.org/viewvc/ant/site/generated/ant_task_guidelines.html?rev=439488&view=auto ============================================================================== --- ant/site/generated/ant_task_guidelines.html (added) +++ ant/site/generated/ant_task_guidelines.html Fri Sep 1 14:41:40 2006 @@ -0,0 +1,494 @@ + + +Apache Ant Task Design Guidelines + + + +

Apache Ant Task Design Guidelines

+ +This document covers how to write Ant tasks to a standard required to be +incorporated into the Ant distribution. You may find it useful when +writing tasks for personal use as the issues it addresses are still +there in such a case. + +

Don't break existing builds

+ +Even if you find some really hideous problem with Ant, one that is easy to fix, +if your fix breaks an existing build file then we have problems. Making sure +that every build file out there still works is one of the goals of all changes. +As an example of this, Ant 1.5 passes the single dollar sign "$" +through in strings; Ant 1.4 and before would strip it. To get this fix in we +first had to write the test suite to expose current behaviour, then change +something so that single "$" was passed through, but double +"$$" got mapped to "$" for backwards compatibility. + +

Don't break the Java API

+ +Ant's tasks can be used by third party programs and tasks. +We cannot make changes that break the API. This includes: +
    +
  1. Moving classes without leaving a backwards-compatible facade. +
  2. Deleting classes. +
  3. Deleting methods or fields, or reducing their accessibility. +
  4. Changing the signature of a setAttribute(Type) method. If you need +to add a restrictive type, add a new attribute, and place it in the source +above the original. The XML mapper will get the restricted type, old programs +can still use the old type. +
  5. Don't change semantics. At least, not drastically. All bug fixes are +implicit changes of semantics, after all. +
+ +

Use built in helper classes

+ +Ant includes helper tasks to simplify much of your work. It is much better to +use them than roll your own, for development, maintenance and code size reasons. + +

Execute

+ +Execute will spawn off separate programs under all the platforms which +Ant supports, dealing with Java version issues as well as platform +issues. Always use this class to invoke other programs. + +

Java, ExecuteJava

+ +These classes can be used to spawn Java programs in a separate VM (they +use execute) or in the same VM--with or without a different classloader. +When deriving tasks from this, it often benefits users to permit the +classpath to be specified, and for forking to be an optional attribute. + +

Project and related classes

+ +Project, FileUtils, JavaEnvUtils all have helper functions to do things like +touch a file, copy a file and the like. Use these instead of coding them +yourself or trying to use tasks which may be less stable and fiddlier to use. + +

Obey the Sun/Java style guidelines

+ +The Ant codebase aims to have a single unified coding standard, and that +standard is the + +Sun Java coding guidelines + +

+ +It's not that they are better than any alternatives, but they are a +standard and they are what is consistently used in the rest of the +tasks. Code will not be incorporated into the database until it complies +with these. + +

+ +If you are writing a task for your personal or organisational use, you +are free to use whatever style you like. But using the Sun Java style +will help you to become comfortable with the rest of the Ant source, +which may be important. + +

+ +One important rule is 'no tabs'. Use four spaces instead. Not two, +not eight, four. Even if your editor is configured to have a tab of four +spaces, lots of others aren't. Spaces have more consistency across +editors and platforms. Some IDEs (JEdit) can highlight tabs, to stop you +accidentally inserting them. +

+There is an Ant build file check.xml in the main ant directory with runs + checkstyle over + Ant's source code. + +

Attributes and elements

+Use the Ant introspection-based mapping of attributes into Java datatypes, +rather than implementing all your attributes as setFoo(String) and doing +the mapping to int, boolean or File yourself. This saves work on your part, +lets Java callers use you in a typesafe manner, and will let the Xdocs +documentation generator work out what the parameters are. + +

+The Ant 1.x tasks are very inconsistent regarding naming of attributes--some +tasks use source, others src. +Here is a list of preferred attribute names: +

+ + + + + + + + + + + + + + + + + + + + + +
+ failonerror + + boolean to control whether failure to execute should throw a + BuildException or just print an error. + Parameter validation failures should always throw an error, regardless + of this flag. +
+ destdir + + destination directory for output +
+ destfile + + destination file for output +
+ srcdir + + source directory +
+ srcfile + + source file +
+

+Yes, this is a very short list. Try and be vaguely consistent with the core +tasks, at the very least. + +

Support classpaths

+ +Try and make it possible for people to supply a classpath to your task, +if you need external libraries, rather than make them add everything to +the ANT_HOME/lib directory. This lets people keep the external libraries +in their Ant-based project, rather than force all users to make changes +to their Ant system configuration. + +

Design for controlled re-use

+ +Keep member variables private. If read access by subclasses is required, +add accessor methods rather than change the accessiblity of the member. +This enables subclasses to access the contents, yet still be decoupled +from the actual implementation. +

+ +The other common re-use mechanism in Ant is for one task to create and +configure another. This is fairly simple. There are facilities available in +Ant's API to have the tasks instantiated by their familiar names +("java", "exec", etc.). It is recommended that you +not use this approach because of the entirely real possibility that a +user has overridden the name to point to a different class entirely. Use direct +constructor calls (or reflection) to instantiate your subtask. Since Ant 1.6.3, +you can call org.apache.tools.ant.Task#bindToOwner() +to "mask" a helper task as its parent. + +

Do your own Dependency Checking

+ +Make has the edge over Ant in its integrated dependency checking; the +command line apps make invokes don't need to do their own work. Ant tasks +do have to do their own dependency work, but if this can be done then +it can be done well. A good dependency-aware task can work out the dependencies +without explicit dependency information in the build file, and be smart +enough to work out the real dependencies, perhaps through a bit of file parsing. +The depends task is the best example of this. Some of the zip/jar +tasks are pretty good too, as they can update the archive when needed. +Most tasks just compare source and destination timestamps and work from there. +Tasks which don't do any dependency checking do not help users as much as +they can, because their needless work can trickle through the entire build, test +and deploy process. + +

Support Java 1.2 through Java 1.5+

+ +Ant 1.5 and lower was designed to support Java 1.1. Ant 1.6 and higher +is designed to support Java 1.2: to build on it, to run on it. Sometimes +functionality of tasks have to degrade in that environment--usually due to +library limitations; such behaviour change must always be noted in the +documentation. +

+What is problematic is code which is dependent on Java 1.3 features; +e.g. java.lang.reflect.Proxy, or Java 1.4 features; e.g. java.io.nio. +Be also aware of extra methods in older classes; +e.g. StringBuffer#append(StringBuffer). These cannot be used directly +by any code and still be able to compile and run on a Java 1.2 system. +If a new method in an existing class is to be used, it must be used via +reflection and the NoSuchMethodException handled somehow. +

+What if code simply does not work on Java 1.2? It can happen. It will +probably be OK to have the task as an optional task, with compilation +restricted to Java 1.3 or later through build.xml modifications. +Better still, use reflection to link to the classes at run time. +

+Java 1.4 adds a new optional change to the language itself, the +assert keyword, which is only enabled if the compiler is told +to compile 1.4 version source. Clearly with the 1.2 compatibility requirement, +Ant tasks cannot use this keyword. They also need to move away from +using the JUnit assert() method and call assertTrue() +instead. +

+Java 1.5 adds the enum type; again, this must not be used. + +

Explicitly Expand properties in nested text

+ +For historical reasons, addText(String text) is called to +set the task's nested text, without any property expansion taking place. +Call Project.replaceProperties() to do this manually. +If you forget, you create a problem that is impossible to fix +without breaking users' build files. + +

Refactor

+ +If the changes made to a task are making it too unwieldy, split it up +into a cleaner design, refactor the code and submit not just feature +creep but cleaner tasks. A common design pattern which tends to occur in +the Ant process is the adoption of the adapter pattern, in which a base +class (say Javac or Rmic) starts off simply, then gets convoluted with +support for multiple back ends: javac, jikes, jvc. A refactoring to +split the programmable front end from the classes which provide the back +end cleans up the design and makes it much easier to add new back ends. +But to carry this off one needs to keep the interface and behaviour of +the front end identical, and to be sure that no subclasses have been +accessing data members directly, because these data members may not +exist in the refactored design. This is why having private data members +is so important. + +

+ +One thing we must not do is move existing tasks around or delete them. +Remember that Ant has a Java API as well as an XML language. We don't want +to break that API, or anything that subclasses existing Ant tasks. When +refactoring, you need to leave facades where the original classes were. so +existing code does not break. + +

Test

+ +Look in ant/src/testcases and you will find JUnit tests for the +shipping Ant tasks, to see how it is done and what is expected of a new +task. Most of them are rudimentary, and no doubt you could do better for +your task--feel free to do so! + +

+ +A well written set of test cases will break the Ant task while it is in +development, until the code is actually complete. And every bug which +surfaces later should have a test case added to demonstrate the problem, +and to fix it. + +

+ +The test cases are a great way of testing your task during development. +A simple call to 'build run-test' in the ant source tree will run all ant +tests, to verify that your changes don't break anything. +To test a single task, use the one shot ant run-single-test +-Dtestcase=${testname} where ${testname} +is the name of your test class. + +

+ +The test cases are also used by the committers to verify that changes +and patches do what they say. If you've got test cases it increases your +credibility significantly. To be precise, we hate submissions without +test cases, as it means we have to write them ourselves. This is +something that only gets done if we need the task or it is perceived as +utterly essential to many users. + +

+ +Remember also that Ant 1.x is designed to compile and run on Java 1.2, so +you should test on Java 1.2 as well as any later version which you use. +You ought to be able to download an old SDK from Sun for this purpose. +

+Finally, run a full build test before and after you start +developing your project, to make sure you haven't broken anything else by +accident. + +

Document

+ +Without documentation, the task can't be used. So remember to provide a +succinct and clear html (soon, xml) page describing the task in a similar +style to that of existing tasks. It should include a list of attributes +and elements, and at least one working example of the task. Many users +cut and paste the examples into their build files as a starting point, +so make the examples practical and test them too. +

+You can use the xdocs stuff in proposal/xdocs to autogenerate your +documentation page from the javadocs of the source; this makes life +easier and will make the transition to a full xdoclet generated +documentation build process trivial. + +

Licensing and Copyright

+ +Any code submitted to the Apache project must be compatible with the +Apache Software License, and the act of submission must be viewed as an +implicit transfer of ownership of the submitted code to the Apache +Software Foundation. + +

+This is important. + +

+ +The fairly laissez-faire license of Apache is not currently considered +compatible with +either the GPL or the Lesser GPL of the Free Software Foundation--the +Gnu project. These licenses have stricter terms, "copyleft", +which are not in the Apache Software Foundation license. +This permits people and organisations to build +commercial and closed source applications atop the Apache libraries and source. + +

+ +Because the Gnu GPL license immediately extends to cover any larger +application (or library, in the case of LGPL) into which it is +incorporated, the Ant team cannot incorporate any task based upon GPL +or LGPL source into the Ant codebase. You are free to submit it, but it +will be politely and firmly rejected. + +

+If you link to a GPL or LGPL library, by import or +reflection, your task must be licensed under the same terms. So tasks +linking to (L)GPL code can't go into the Apache managed codebase. +Tasks calling such code can use the 'exec' or 'java' tasks to run the +programs, as you are just executing them at this point, not linking to +them. +

+Even if we cannot include your task into the Apache codebase, we can +still point to where you host it; just submit a diff to +xdocs/external.html pointing to your task. +

+If your task links directly to proprietary code, we have a different +problem: it is really hard to build the tasks. Please use reflection. + +

Don't re-invent the wheel

+ +We've all done it: written and submitted a task only to discover it +was already implemented in a small corner of another task, or it has +been submitted by someone else and not committed. You can avoid this +by being aware of what is in the latest CVS tree; keep getting the daily +source updates, look at manual changes and subscribe to the dev +mailing list. + +

+ +If you are thinking of writing a task, posting a note on your thoughts +to the list can be informative--you will get other peoples' insights and +maybe some half-written task to do the basics, all without writing a +line of code. + +

Submitting to Ant

+ +The basic mechanism for submitting an Ant task is to mail it to the +dev mailing list. It helps to be on this list, as you will see other +submissions, and any debate about your own submission. +

+You may create your patch file using either of the following approaches +(the committers recommend the first): +

+

    +
  • Approach 1 - The Ant Way

    +

    +Use Ant to generate a patch file to Ant: +

    +ant -f patch.xml
    +
    +This will create a file named patch.tar.gz that will contain a unified +diff of files that have been modified and also include files that have +been added. Review the file for completeness and correctness. This approach +is recommended because it standardizes the way in which patch files are +constructed. It also eliminates the chance of you missing to submit new files +that constitute part of the patch. +

    +

  • Approach 2 - The Manual Way

    +

    +Patches to existing files should be generated with +svn diff -u filename + and save the output to a file. If you want to get +the changes made to multiple files in a directory , just use cvs +diff -u. Then, Tar and GZip the patch file as well as any new files +that you have added. +

+

+The patches should be sent as an attachment to a message titled [PATCH] +and distinctive one-line summary in the subject of the patch. The +filename/task and the change usually suffices. It's important to include +the changes as an attachment, as too many mailers reformat the text +pasted in, which breaks the patch. +

+Then you wait for one of the committers to commit the patch, if it is +felt appropriate to do so. Bug fixes go in quickly, other changes +often spark a bit of discussion before a (perhaps revised) commit is +made. +

+ +New submissions should be proceeded with [SUBMIT]. The mailer-daemon +will reject any messages over 100KB, so any large update should be +zipped up. If your submission is bigger than that, why not break it up +into separate tasks. +

+ +We also like submissions to be added to +bugzilla, so that they dont get lost. Please submit them by first filing the report with a +meaningful name, then adding files as attachments. Use CVS diff files +please! +

+ +If you hear nothing after a couple of weeks, remind the mailing list. +Sometimes really good submissions get lost in the noise of other issues. +This is particularly the case just prior to a new point release of +the product. At that time anything other than bug fixes will tend +to be neglected. + +

Checklists

+ +These are the things you should verify before submitting patches and new +tasks. Things don't have to be perfect; it may take a couple of +iterations before a patch or submission is committed, and these items +can be addressed in the process. But by the time the code is committed, +everything including the documentation and some test cases will have +been done, so getting them out the way up front can save time. +The committers look more favourably on patches and submissions with test +cases, while documentation helps sell the reason for a task. + +

Checklist before submitting a patch

+
    +
  • Added code complies with style guidelines +
  • Code compiles and runs on Java 1.2 +
  • New member variables are private, and provide public accessor methods + if access is actually needed. +
  • Existing test cases succeed. +
  • New test cases written and succeed. +
  • Documentation page extended as appropriate. +
  • Example task declarations in the documentation tested. +
  • Diff files generated using svn diff -u +
  • Message to dev contains [PATCH], task name and patch reason in +subject. +
  • Message body contains a rationale for the patch. +
  • Message attachment contains the patch file(s). +
+ +

Checklist before submitting a new task

+
    +
  • Java file begins with Apache copyright and license statement. +
  • Task does not depend on GPL or LGPL code. +
  • Source code complies with style guidelines +
  • Code compiles and runs on Java 1.2 +
  • Member variables are private, and provide public accessor methods + if access is actually needed. +
  • Maybe Task has failonerror attribute to control failure behaviour +
  • New test cases written and succeed +
  • Documentation page written +
  • Example task declarations in the documentation tested. +
  • Patch files generated using svn diff -u +
  • patch files include a patch to defaults.properties to register the +tasks +
  • patch files include a patch to coretasklist.html or +optionaltasklist.html to link to the new task page +
  • Message to dev contains [SUBMIT] and task name in subject +
  • Message body contains a rationale for the task +
  • Message attachments contain the required files -source, documentation, +test and patches zipped up to escape the HTML filter. +
+
+

Copyright © 2001-2003, 2005-2006 Apache Software Foundation. All rights +Reserved.

+ + Propchange: ant/site/generated/ant_task_guidelines.html ------------------------------------------------------------------------------ svn:eol-style = native Added: ant/site/generated/antlibs/antunit/index.html URL: http://svn.apache.org/viewvc/ant/site/generated/antlibs/antunit/index.html?rev=439488&view=auto ============================================================================== --- ant/site/generated/antlibs/antunit/index.html (added) +++ ant/site/generated/antlibs/antunit/index.html Fri Sep 1 14:41:40 2006 @@ -0,0 +1,318 @@ + + + + + + + + Apache Ant - AntUnit + + + + + + +
+ + + + + + +
Apache Ant siteApache Ant logo +
+ + + + + + + + + + + + + + +
+ + + + +
+ the Apache Ant site +
+
+
+
+ +
+ + + + + +
+ + + + +
Home
+
+ + + + +
Projects
+
+
+ +
+ + +
 
+
+
+

AntUnit

+

+ + Idea +

+

Initially all tests for Ant tasks were written as individual + JUnit test cases. Pretty + soon it was clear that most tests needed to perform common tasks + like reading a build file, initializing a project instance with + it and executing a target. At this point BuildFileTest + was invented, a base class for almost all task test cases.

+

BuildFileTest works fine and in fact has been picked up by the Ant-Contrib Project + and others as well.

+

Over time a new pattern evolved, more and more tests only + executed a target and didn't check any effects. Instead that + target contained the assertions as a <fail> + task. This is an example taken from the build file for the + ANTLR task (using Ant 1.7 features):

+
+  <target name="test3" depends="setup">
+    <antlr target="antlr.g" outputdirectory="${tmp.dir}"/>
+    <fail>
+      <condition>
+        <!-- to prove each of these files exists;
+             ANTLR >= 2.7.6 leaves behind new (.smap) files as well. -->
+        <resourcecount when="ne" count="5">
+          <fileset dir="${tmp.dir}">
+            <include name="CalcParserTokenTypes.txt" />
+            <include name="CalcParserTokenTypes.java" />
+            <include name="CalcLexer.java" />
+            <include name="CalcParser.java" />
+            <include name="CalcTreeWalker.java" />
+          </fileset>
+        </resourcecount>
+      </condition>
+    </fail>
+  </target>
+
+

where the corresponding JUnit testcase has been reduced + to

+
+...
+public class ANTLRTest extends BuildFileTest {
+
+    private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/antlr/";
+
+    public ANTLRTest(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        configureProject(TASKDEFS_DIR + "antlr.xml");
+    }
+
+    public void tearDown() {
+        executeTarget("cleanup");
+    }
+
+    public void test3() {
+        executeTarget("test3");
+    }
+...
+}
+
+

This approach has a couple of advantages, one of them is that + it is very easy to translate an example build file from a bug + report into a test case. If you ask a user for a testcase for a + given bug in Ant, he now doesn't need to understand JUnit or how + to fit a test into Ant's existing tests any more.

+

AntUnit takes this approach to testing even further, it + removes JUnit completely and it comes with a set of predefined + <assert> tasks in order to reuse common kind + of checks.

+

It turns out that AntUnit lends itself as a solution to other + problems as well. The assertions are an easy way to validate a + setup before even starting the build process, for example. + AntUnit could also be used for functional and integration tests + outside of the scope of Ant tasks (assert contents of databases + after running an application, assert contents of HTTP responses + ...). This is an area that will need more research.

+

+ + Concepts +

+

+ + antunit Task +

+

The <antunit> task drives the tests much like + <junit> does for JUnit tests.

+

When called on a build file, the task will start a new Ant + project for that build file and scan for targets with names + that start with "test". For each such target it then will

+
    +
  1. Execute the target named setUp, if there is one.
  2. +
  3. Execute the target itself - if this target depends on + other targets the normal Ant rules apply and the dependent + targets are executed first.
  4. +
  5. Execute the target names tearDown, if there is one.
  6. +
+

+ + Assertions +

+

The base task is <assertTrue>. It + accepts a single nested condition and throws a subclass of + BuildException named AssertionFailedException if that + condition evaluates to false.

+

This task could have been implemented using + <macrodef> and <fail>, + but in fact it is a "real" task so that it is possible to + throw a subclass of BuildException. The + <antunit> task catches this exception and + marks the target as failed, any other type of Exception + (including other BuildException) are test errors.

+

Together with <assertTrue> there are + many predefined assertions for common conditions, most of + these are only macros.

+

+ + Other Tasks +

+

The <logcapturer> captures all messages + that pass Ant's logging system and provides them via a + reference inside of the project. If you want to assert + certain log messages, you need to start this task (prior to + your target under test) and use the + <assertLogContains> assertion.

+

<expectFailure> is a task container that + catches any BuildException thrown by tasks nested into it. If + no exception has been thrown it will cause a test failure (by + throwing an AssertionFailedException).

+

+ + AntUnitListener +

+

Part of the library is the AntUnitListener + interface that can be used to record test results. The + <antunit> task accepts arbitrary many listeners and + relays test results to them.

+

Currently two implementations - + <plainlistener> and xmllistener + modelled after the "plain" and "xml" + JUnit listeners - are bundled with the library.

+

+ + Examples +

+

This is a way to test that <touch> + actually creates a file if it doesn't exist:

+
+<project xmlns:au="antlib:org.apache.ant.antunit">
+  <!-- is called prior to the test -->
+  <target name="setUp">
+    <property name="foo" value="foo"/>
+  </target>
+
+  <!-- is called after the test, even if that caused an error -->
+  <target name="tearDown">
+    <delete file="${foo}" quiet="true"/>
+  </target>
+
+  <!-- the actual test case -->
+  <target name="testTouchCreatesFile">
+    <au:assertFileDoesntExist file="${foo}"/>
+    <touch file="${foo}"/>
+    <au:assertFileExists file="${foo}"/>
+  </target>
+</project>
+
+

When running a task like

+
+    <au:antunit>
+      <fileset dir="." includes="touch.xml"/>
+      <au:plainlistener/>
+    </au:antunit>
+
+

from a buildfile of its own you'll get a result that looks like

+
+[au:antunit] Build File: /tmp/touch.xml
+[au:antunit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.249 sec
+[au:antunit] Target: testTouchCreatesFile took 0.183 sec
+
+BUILD SUCCESSFUL
+Total time: 1 second
+
+ +
+
+ + + + + + + + + + + + + + + Propchange: ant/site/generated/antlibs/antunit/index.html ------------------------------------------------------------------------------ svn:eol-style = native Added: ant/site/generated/antlibs/bindownload.cgi URL: http://svn.apache.org/viewvc/ant/site/generated/antlibs/bindownload.cgi?rev=439488&view=auto ============================================================================== --- ant/site/generated/antlibs/bindownload.cgi (added) +++ ant/site/generated/antlibs/bindownload.cgi Fri Sep 1 14:41:40 2006 @@ -0,0 +1,6 @@ +#!/bin/sh +# Wrapper script around mirrors.cgi script +# (we must change to that directory in order for python to pick up the +# python includes correctly) +cd /www/www.apache.org/dyn/mirrors +/www/www.apache.org/dyn/mirrors/mirrors.cgi $* Propchange: ant/site/generated/antlibs/bindownload.cgi ------------------------------------------------------------------------------ svn:executable = * --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org For additional commands, e-mail: dev-help@ant.apache.org