Apache Commons BeanUtilsを使ったときにはまったことのメモ
確認したバージョン
- Java 8
- Apache Common BeanUtils 1.8.3~1.9.4
検証コード
Bean.java
public class Bean {
private Timestamp timestamp;
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
}
Main.java
public class Main {
public static void main(String[] args) throws Exception {
Bean bean = new Bean();
// 1.9.3以前では、Object.getClass()をアクセサと解釈して"class"がプロパティ一覧に含まれる。
BeanUtils.describe(bean);
// => 1.9.3以前:{class=class test.Bean, timestamp=null}
// 1.9.4:{timestamp=null}
// ※ PropertyUtils.describe(bean) も同様の結果となる。
// 1.9.3以前では、setPropertyとcopyPropertyでアクセスできないプロパティを設定したときの挙動が異なる。
BeanUtils.setProperty(bean, "class", Bean.class);
// => 何も実行されない。
BeanUtils.copyProperty(bean, "class", Bean.class);
// => 1.9.3以前:java.lang.reflect.InvocationTargetException: Cannot set class が発生する。
// 1.9.4:何も実行されない。(BEANUTILS-520の影響で振る舞いが変わった?)
// setPropertyとcopyPropertyで一部の型のプロパティにnullを設定しようとしたときの挙動が異なる。
BeanUtils.setProperty(bean, "timestamp", null);
// => org.apache.commons.beanutils.ConversionException: No value specified for 'java.sql.Timestamp' が発生する。
BeanUtils.copyProperty(bean, "timestamp", null);
// => 1.8.3以前:copyProperty同様にConversionExceptionが発生していた。
// 1.9.0以降:何も実行されない。(BEANUTILS-454にて修正)
}
}