Wednesday, August 6, 2008

ZIP gotcha: you could be a few milliseconds from build failure

In Apache Ant's documentation, you will find the following notice in the description of the Zip task: Please note that ZIP files store file modification times with a granularity of two seconds. If a file is less than two seconds newer than the entry in the archive, Ant will not consider it newer.

I had never really paid attention to this, until I actually ran into a situation where it creates a problem: in a build script, I need to extract a deployment descriptor from a generated EAR, modify it, and rezip it in the EAR (ugly, but I really don't have any control over the generation of the EAR).

So what had to happen happened: the interval between the generation of the EAR and the time I make my modification is less than two seconds. But, in the true spirit of Murphy's law, it is not always less: on my machine and during the nightly build, it takes slighty longer, which explains why I hadn't seen the problem in the first place. But when the build is run manually on the integration server, the interval suddendly becomes slightly shorter than two seconds (probably due to a higher process priority), and the descriptor is not updated.

I added an artificial two-second pause to make sure that the modified file will always be "newer enough".

By the way, this is not specific to Ant. From Wikipedia: The FAT filesystem of DOS only has a timestamp resolution of two seconds; ZIP file records mimic this. As a result, the built-in timestamp resolution of files in a ZIP archive is only two seconds, though extra fields can be used to store more accurate timestamps.

1 comments:

Manu said...

Bad luck.
Wonder if I would have found such a tricky one.