- - PR -
J2SDKのバージョンアップによる動きの違い
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-12-25 14:00
業務アプリケーションのバージョンアップに伴い、J2SDKを1.4.2_05から1.4.2_16にあげたところ、org.apache.commons.beanutils.PropertyUtilsのメソッドcopyPropertiesで、実行時例外が発生しました。
詳しくソースを追ってデバックしたところ、JavaBeansのゲッターセッターがあいまいになる条件でjava.beans.PropertyDescriptor の動きが異なるようです。 サンプルコードでは、1.4.2_05で問題なく「OK.」となりますが、1.4.2_16では、例外を投げます。 SUNのbug databaseで調べても近くて異なる該当項目しか見当たらなかったので、報告しようか迷っています。 それとも、JavaBeansの仕様が厳密になったというアナウンス等があったのでしょうか? (OS: Windows XP Pro SP2) サンプルコード ▼[Value.java] /** * JavaBeans のオブジェクト * * setIdArray と getIdArray のオーバーロードされたメソッドがある。 * * 上記のような条件を満たすメソッドがある場合に、 * java.beans.PropertyDescriptor クラスの * getWriteMethod メソッド、getReadMethod メソッドは、 * J2SDK のバージョンにより異なる動きをみせる。 * * @author Shrike * */ public class Value { private String[] idArray; public void setIdArray(String[] idArray) { this.idArray= idArray; } public String[] getIdArray() { return idArray; } public Integer getIdArray(final int index) { return null; } public void setIdArray(final int index, final Integer id) { } } ▼[PropertyDescriptorVerify.java] import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; /** * PropertyDescriptorクラスの getWriteMethodメソッドを検証します。 * * @author Shrike * */ public class PropertyDescriptorVerify { /** * PropertyUtilsの動作を真似て、 getWriteMethodメソッドを検証します。 * @throws Exception * @throws Exception */ public static void main(String[] args) throws Exception { String name = "idArray";// Value オブジェクトのフィールド名前 Value value = new Value();// 対象となるJavaBeans オブジェクト // value の BeanInfo を取得 BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(value.getClass()); } catch (IntrospectionException e) { } // PropertyDescriptor の配列を取得 PropertyDescriptor descriptors[] = beanInfo.getPropertyDescriptors(); // 指定したフィールド名のアクセッサを持つ PropertyDescriptorを取得。 PropertyDescriptor descriptor = null; for (int i = 0; i < descriptors.length; i++) { //動作確認 System.out.println("index: " + i); System.out.println("name: " + descriptors[i].getName()); System.out.println("propertyType: " + descriptors[i].getPropertyType()); System.out.println("readMethod: " + descriptors[i].getReadMethod()); System.out.println("writeMethod: " + descriptors[i].getWriteMethod()); System.out.println(""); String accessorTarget = descriptors[i].getName(); if (name.equals(accessorTarget)) { descriptor = descriptors[i]; break; } } if (descriptor == null) { // null の時は例外を発生(org.apache.commons.beanutils.PropertyUtils と同じ動き) throw new NoSuchMethodException("Unknown property '" + name + "'"); } Method writeMethod = descriptor.getWriteMethod(); if (writeMethod == null) { // null の時は例外を発生(org.apache.commons.beanutils.PropertyUtils と同じ動き) throw new NoSuchMethodException("Property '" + name + "' has no setter method"); } System.out.println("OK."); } } [ メッセージ編集済み 編集者: Shrike 編集日時 2007-12-27 00:53 ] | ||||
|
投稿日時: 2007-12-27 14:26
その部分に関しては明確に文書化されていない、いわゆる実装依存の範疇だと考えます。beans仕様の8. 自己検査には
今回のような曖昧なプロパティを含むbeanを扱うときは、明示的にBeanInfoを記述するのが一番確実だと思います。 また、1.4.2_05 と 1.4.2_16 で振る舞いが違う事に関しては1.4.2 のリリースノートをざっと見てみましたけど、5109847 のjava.beans.Introspector の退行 (プロパティの再順序付け)というのが一番怪しいかもしれません。 | ||||
|
投稿日時: 2007-12-27 16:34
参考文献のご提示ありがとうございます。
リリースノートについては、私の方でもチェックしておりました。 「java.beans.Introspector の退行」は、bug database を見る限りでは、ステータスがclose, fixed になっているので、どうしたものかと思っていたところでもあります。 特殊な条件における修正漏れの可能性はありえそうですよね。 PropertyUtilsは、メモリリークをするとの噂も聞いたので、今回はこれを使わない方向で、対応することになりました。 新しく何か情報がわかりましたら、よろしくお願い致します。 こちらでも、何かわかった際には追記したいと思います。 ありがとうございました。 | ||||
|
投稿日時: 2007-12-27 19:27
すいません説明不足だったようです。
件のPropertyDescriptorVerifyでreadMethodとwriteMethodがnullのPropertyDescriptorを返すのは実装者によって期待された動作なのではないかと考えます。 このreadMethod、writeMethodがnullのPropertyDescriptorはIndexedPropertyDescriptor のインスタンスで、getIndexedReadMethod()やgetIndexedWriteMethod()を使えば Value#getIdArray(int)やValue#setIdArray(int, Integer)が得られるはずです。そして、この動作は1.3.1_20と同じ動作です。また、1.2.2_017で同じ事をするとインデクス付きプロパティとインデクス無しのプロパティの要素型が代入互換でないにも関わらず
|
1