An evil trick with Ant
July 24th, 2006 by HenI’ve been having a bit of fun at work recently with Ant. We build lots of open source projects using the original Ant build systems that have been tweaked via overriding, setting properties early and various other mundane tricks. It’s a bit of a slog as often it’s not just a case of having to set some properties or override a task, but to fully understand yet another different build system. One particular bit that has been a pain is wanting to enforce that all JUnit tasks generate XML reports.
My first thoughts were to hack a new build of JUnit - but looking at the source I realised that all the exciting work happens in the Ant task. So next up was to hack a new build of the JUnitTask in Ant. Fortunatley my laziness intervened and I read on. You see, Ant has these things called BuildListeners. They tell you when a build starts, when one ends, when a particular task starts etc etc. Useful for logging. Or being an evil dictator build guy…
Given that I know that a JUnit task has begun and through its Event object I have access to the Ant version of the DOM - I can insert my own modifications. Mandatory changes that the build system has no choice but to accept. The basic for Aspect Ant if you would (yes I know you could just use Aspects on the Java, but that’s a lot more painful I suspect.
Here’s the relevant part of the BuildListener implementation:
public void taskStarted(BuildEvent event) {
if(event.getTask().getTaskName().equals("junit")) {
UnknownElement ue = (UnknownElement) event.getTask();
RuntimeConfigurable rc = ue.getWrapper();
rc.setAttribute("haltonfailure", "false");
rc.setAttribute("haltonerror", "false");
UnknownElement ue2 = new UnknownElement("formatter");
ue.addChild(ue2);
FormatterElement fe = new FormatterElement();
RuntimeConfigurable rc2 = new RuntimeConfigurable(fe, "formatter");
rc2.setAttribute("type", "xml");
rc.addChild(rc2);
}
}
Here’s what the manual has to say on build listeners, and here’s the Javadoc for org.apache.tools.ant.BuildListener.

August 2nd, 2006 at 7:42 am
I’m commenting to point out to the community that is the recommended way to do these things despite my awareness of your reasons for rejecting it in this instance, Henri.