2008.10.23

久しぶりに古いバージョンのJavaを利用して嵌りました

最近、久しぶりに古いバージョンのJavaを利用して嵌りました。
なぜなら、JDK/JRE V1.2.x、V1.3.xには、java.util.Calenderクラスに不具合があるからなのです。

抽象クラスであるjava.util.Calenderクラスの具象クラス(java.util.GregorianCalenderクラス)及び、
その派生クラスにて閏年の12月31日を扱った際に、エラーが発生する場合があります。

■発生条件
 以下の全て条件を満たす時、java.lang.IllegalArgumentExceptionが発生することがある。

1)JDKまたはJREの1.2.0、1.2.1、1.2.2、1.3.0、1.3.1を使用する。(パッチレベルは省略)
2)java.util.GregorianCalendarクラス、または、java.util.GregorianCalenderクラスを継承したクラス、
 または、java.util.CalenderクラスのgetInstance()メソッドにて取得したクラスを使用している。
3)setLenient(false)を実行する。
4)以下のいずれかの方法で、閏年の12月31日の日付を設定する。

4-1)システム日付が、閏年の12月31日の時、java.lang.Calendar.getInstance()または、
  new java.util.GregorianCalendar()を実行する。

4-2)set()メソッドで閏年の12月31日の値を設定する。
  かつ、getTime(),add(),roll(), get(),computeTime(),getTimeInMillis(),complete(), computeFields()
  のいずれかのメソッドを実行する。

4-3)setTime()メソッド、setTimeInMillis()メソッドで閏年の12月31日の値を設定する。

4-4) add()メソッドによる計算により、閏年の12月31日の値を設定する。

5)同じオブジェクトに対し引き続き、set()メソッドで、閏年以外の値を設定する。
6)getTime(), equals(), before(), after(), add(), roll(), get()
computeTime(), getTimeInMillis(), complete()のいずれかのメソッドを実行した場合。

■回避例
1)別の日付を設定する直前に(発生条件5)の直前に、Calendar.clear()を呼ぶ。
2)別の日付を設定する際は、新たにインスタンス化したオブジェクトを使用する。

今回は、昔のことをすっかり忘れていた為、嵌ってしまいました。
昔、社内でも報告した記憶があるのですが。。。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

photo
ykato