Jon Aquino First Video Game Written In Ant (via Dion).

path: /en/Apache/Ant | #

Steve talks about a feature in Py.test: remember which tests failed the last time and only test these on the next run. He also hints how we could use Ant's test runner to do the same with JUnit. Well, I think we are already there:

1. Save to a file a list of all tests classes that contained a failing test

We can use a custom <formatter> for this. Without the gory details of error handling, it basically would look like

// abusing as NullObject Adapter
public class FailureRecorder extends SummaryJUnitResultFormatter {

    // will hold class names of failed tests, we don't need duplicates
    private HashSet failedTests = new HashSet();

    // out is private in SummaryJUnitResultFormatter
    private OutputStream out;

    // out is private in SummaryJUnitResultFormatter, intercept setter
    public void setOutput(OutputStream out) {
        this.out = out;

    public void addFailure(Test test, Throwable t) {

    public void addError(Test test, Throwable t) {

    private void add(Test test) {
        // this relies on Test being the actual test class and not a TestSuite
        // or any other decorator
        String c = test.getClass().getName().replace('.', '/');
        failedTests.add(c + ".class");

    public void endTestSuite(JUnitTest suite) {
        if (out != null && failedTests.size() > 0) {
            PrintWriter w = new PrintWriter(new OutputStreamWriter(out));
            Iterator iter = failedTests.iterator();
            while (iter.hasNext()) {

This would leave us with a file holding the class file names of all failing tests in a format suitable for <fileset>'s includesfile attribute.

Unfortunately we'll have one file per TestSuite, which means one file per test class in normal operation mode. The easiest way to join them is using the <concat> task afterwards. So the full sequence would look like

  <junit ...>
    <batchtest todir="reports-dir">
    <formatter classname="FailureRecorder" extension="failures"/>
  <concat destfile="last-failures" fixlastline="true">
    <fileset dir="reports-dir" includes="*.failures" id="failing-tests"/>
    <fileset refid="failing-tests"/>
2. When rerunning, build up a fileset that only contains those test classes.

Trivial, use the file just created in

  <junit ...>
      <fileset dir="my-compiled-tests" includesfile="last-failures"/>

It may be worth to brush up the code a little and include such a formatter with Ant.

Updated since the first version would have written multiple files.

path: /en/Apache/Ant | #

During discussions on whether a project at the ASF should migrate from CVS to Subversion somebody raised "even Ant doesn't support Subversion". This really surprised me.

First Ant's CVS support isn't really that intriguing either. There is a thin wrapper on top of the cvs command line client, a task to modify ~/.cvspass and two tasks to generate XML versions of some historical reports generated from "cvs log" or "cvs diff".

Second, there are Ant tasks for Subversion, just not as part of the default Ant installation. The projects I know are

and I bet there is more if you just search around a bit.

Since people seem to insist that only tasks coming from Ant itself are acceptable in their shop, I've started to put together a few tasks that match Ant's support for CVS. This is nothing too fancy and will probably never be more than a layer on top of the svn command line client. A basic <svn> task and three tasks for historic reports using a format very similar to Ant's CVS reports can be found as rough versions in Ant's CVS sandbox. I don't actually plan to propose their inclusion with Ant, but rather develop them as an independent Ant library.

People who want to check out the tasks probably need Ant from CVS HEAD as well since I haven't checked for Ant 1.6.2 compatibility yet.

path: /en/Apache/Ant | #

I've applied Andrew Choi's patches and now I have two XEmacsen (21.5.18) running on my iBook, the "original" X version and a Carbon version.

They seem to perform roughly the same, with the X version using a little bit less of memory. I personally prefer the tool-bar icons of the X version and for some reason the Carbon version starts with a dark background by default.

So far I couldn't find a place where the Carbon XEmacs would integrate better with native Mac stuff than the X version: copy-paste works the same in both, drag-n-drop (which I don't need) doesn't work in either, the Fonts menu under Options is empty in both. Of course I can have Carbon XEmacs in my dock more easily.

Running Gnus I notice the first real differences, buttonizing of URLs or attachment placeholders doesn't seem to work in Carbon XEmacs, which is rather annoying.

And then I tried to write some code and compile it. Soon I get reminded of my ~/.Xmodmap or better why I have one. I still haven't found a way to disable dead-keys for Cocoa or Carbon apps - having to press space after C-x ` is annoying. Carbon XEmacs doesn't seem to recognize my German keyboard layout, which makes things worse.

For now I'm going to stick with the X version of XEmacs.

path: /en/Mac/XEmacs | #

Sam puts the news into perspective and he's certainly right about it. It still takes a lot of effort to attack a SHA-1 digest. But it also means you should be looking for something else if security is a really important issue.

path: /en/crypto | #

via Bruce Schneier.

MD5 is unusable since last August and SHA-1 was recommended as a replacement as hash function for digital signatures. No more.

Update: Eugene Kuleshov provides some pointers to alternatives in the Java world.

path: /en/crypto | #

With Java 5.0, the Comparable interface has been made "generic" and quite a few classes have been retro-fitted to make use of this, for example, java.math.BigDecimal now implements Comparable<BigDecimal>. Unfortunately the developers of the Java classlib forgot to preserve the old signature of compareTo with an Object argument. This means that a method has gone without any deprecation at all. Code that compiles fine in JDK 1.4 no longer compiles and no -source switch is going to help.

For example, see Castor's build in Gump:

    [javac] .../src/main/org/exolab/castor/persist/ compareTo(java.math.BigDecimal) in java.math.BigDecimal cannot be applied to (java.lang.Object)
    [javac]         if ( (o1 instanceof java.math.BigDecimal) && ((java.math.BigDecimal) o1).compareTo(o2) == 0) {

While I understand why BigDecimal can't implement Comparable<BigDecimal> and Comparable<Object> at the same time (erasure is the key), adding a compareTo(Object) method to Number would have fixed the problem for quite a few classes. I think this is a bug, but the Sun team seems to disagree - or at least think it is not significant.

This means that you need to use explicit casts in your code when you invoke compareTo. Casts that have been unnecessary in JDK 1.4.

path: /en/Java | #

Here's the message Ken has sent to a couple of announce lists:

The Call for Participation for ApacheCon Europe 2005 is open! ApacheCon will be returning to Europe for the first time since 2000, and this time we'll be in Stuttgart, Germany, from the 18th through the 22nd of July, 2005. If you'd like to give a presentation, please go to the Web site (http://ApacheCon.Com/2005/EU/) and submit a proposal. Or more than one! *The deadline is 4 March 2005.* Please feel free to forward this message far and wide.

path: /en/Apache/ApacheCon | #

A while back I promised to talk about Gump running on Kaffe.

Dims and a few of us Apache Gump people work together with Dalibor and a few other Kaffe people and try to build as much as possible on the Kaffe VM.

The problems we've solved so far

So far it has been a lot of fun to see the number of projects we managed to build in Gump increase with every hurdle we jump over. Every now and then Kaffe is broken, or I break Ant's bootstrap process for Kaffe. But the general direction is very positive. On good days we've been able to build ~25% of all projects Gump wants to build - on JDK 1.4 we manage to build ~85% of them, on JDK 1.5 ~60%.

path: /en/Apache/Gump | #