- PR -

EJBにオブジェクトが渡せない→ClassCastException

1
投稿者投稿内容
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2005-11-02 22:02
EJBの引数としてHashMapを渡しています。
そして、HashMapに自作クラスをセットしています。

EJB側で、HashMapから自作クラスを取り出して
自作クラス名で取り出そうとするとClassCastExceptionが発生します。

自作クラスは、以下のような超シンプルクラスです。
public class Test implements Serializable {

String aaa;
public String getAaa() {
return aaa;
}

public void setAaa(String aaa) {
this.aaa = aaa;
}
}

ブレークポイントで止めて、HashMapをのぞくと
ちゃんとTestクラスがわたってきているのが見えています。

Object o = map.get("key");
System.out.println(o.getClass());
↑のようにやっても、ちゃんとTestクラスの名前が表示されます。(もちろんフルパスで正しいです)
しかし↑の後に
Test test = (Test)o;
とやると、ClassCastExceptionが発生してしまいます。
こんなことってあるのでしょうか?

ちなみに、HashMapにString等をつめた場合は問題なく動作します。

どなたかご教授下さい。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-11-02 22:22
そんなあなたに BEA サポートパターン
・BEA トラブルシューティング ガイド サポート診断パターン > ClassCastException の調査
http://www.beasys.co.jp/cs/support_news/product_troubleshooting/Class_Cast_Exceptions_Pattern.html
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2005-11-02 22:35
ClassCastExceptionがこんなに奥が深いとは。

たしかに
>System.err.println("The object " + o + " classloader is " + o.getClass>().getClassLoader());
>System.err.println("Class Foo class loader is " + Foo.class.getClassLoader());
↑をおこなったところ、クラスローだが違うために発生しているようです。

以下、実行結果。
[02/11/2005 22:34:46:428 +0900] The object com.xxx.Test@1b0edb2 classloader is StandardClassLoader
[02/11/2005 22:34:47:330 +0900] Class Foo class loader is com.fujitsu.interstage.j2ee.ijserver.loader.ApplicationClassLoader@b957ea

でも、まだ回避方法がわからないです。引き続き追ってみます。

[ メッセージ編集済み 編集者: 頭脳パン 編集日時 2005-11-02 22:36 ]
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2005-11-02 22:49
できました〜。
Interstageに、クラスローダを分離しないっていう
設定があって、この設定を行ったら解決しました。

ちょっと原因不明すぎて、青くなっていたのですが
ありがとうございます〜。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-11-02 22:52
読み込まれているクラスローダが違うってことはクラスの置かれている場所に問題がある可能性があります。
Interstage のクラスローダの構成がどうなっているかは存じ上げないのですが、EJBのメソッド呼出は参照渡しになっているようですので、EJBのクライアント側、EJBが動く側両方から見える場所にクラスを配置しましょう。

呼出を参照渡しではなく値渡し(call by reference)にすることで回避できる可能性もあります。値渡しの場合は引数、返値は一旦シリアライズされてそれぞれのクラスローダでオブジェクトがデシリアライズされるからです。
パフォーマンスは悪くなりますが。
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2005-11-04 11:01
>読み込まれているクラスローダが違うってことはクラスの置かれている場所に問題がある可能性があります。
おっしゃるとおり、問題のクラスは、クラスパスに通しているものと
APサーバに配備したものと2つありました。
これを1つにしたら解決しました。
こちらの解決方法の方がベターそうなので
「クラスローダを分離しない」の設定は元に戻しました。
1

スキルアップ/キャリアアップ(JOB@IT)