差分表示


*概要
昨日(2008-02-29)たまたまJakarta-Apache Commons Net 1.4.1のFTPをつかっていて、FTPListParseEngne.getFiles()の戻り値に昨日日付のファイルが含まれない事象を観測しちゃいました。

調べてみると、FTPサーバから拾ったrawのfile entryは閏日日付のファイルも含まれるのですが、戻り値のFTPFileインスタンスを生成する処理中で、サーバの結果の行からFTPFileインスタンスのフィールドに値を刺す箇所でエラーになるため、閏日日付のファイルのエントリがなくなっていることがわかりました。

具体的には、タイムスタンプの部分を切り取って SimpleDateFormat.parse(String tstr, ParsePosition pp)に食わせるところで、閏日の場合は java.util.Dateのインスタンスが返らないで、parseエラーを示すnullが返り、その場合の対象行は%%%爽やかにExceptionも出さずになかったことにする%%%という感じになってました。この結果サーバに存在してFTPサーバの応答に含まれるファイルが getFiles()の結果に含まれなくなります。

*詳細
[[既に調べた方がいらっしゃいます>http://tmaeda.s45.xrea.com/td/20080229.html]]ので、こっちを見たほうが良さそうです。

*原因
org/apache/commons/net/ftp/parser/FTPTimestampParserImplのコメントに書いてあるので、そっちを抜粋しました。
---(
// Temporarily add the current year to the short date time
// to cope with short-date leap year strings.
// e.g. Java's DateFormatter will assume that "Feb 29 12:00" refers to 
// Feb 29 1970 (an invalid date) rather than a potentially valid leap year date.
// TODO This is a HORRENDOUS hack. Remove at first opportunity.
---)

なので、このバグが発生するのは''2/29に作成されたファイルを同じ年の半年以内にlistした場合''(=FTPサーバからの応答では、今年の場合の書式が MMM dd HH:ssになり、現在時刻とのdeltaが半年の場合は MMM dd yyyy)になります。自前でテストしてたときは先週(2008-02-23付近)なので、テストする上で4年前の閏年の日付を使っていたのですが、その場合に本事象は発生せず、気がつきませんでした。 orz

*修正
http://svn.apache.org/viewvc?view=rev&revision=631284

Commons Netの本体を差し替えてbuildしましょう。

*そのほか
-1. バグを追うときに、jdbを使っていたのでその取説でも書こうと思ったんですが、燃え尽きましたw 気が向いたら書きます。
-2. RHEL-AS4u4のstrptime(3)で試す限り、%b %dとして Feb 29をparseすると異常値になってます。で、Commons Netのwkrdみたいに %b %d %Yとしてparseすると適正な値になってたりします。
//-2. RHEL-AS4u4のstrptime(3)で試す限り、%b %dとして Feb 29をparseすると異常値になってます。で、Commons Netのwkrdみたいに %b %d %Yとしてparseすると適正な値になってたりします。


Last-modified: 2008-03-03 19:34:07