9

2つの異なるWebアプリがあり、それぞれが異なるクラスローダーで同じクラスAをロードします。1つのインスタンスをセッションに配置し、それを他のWebアプリから取得すると、aClassCastExceptionがスローされます。

たとえば、webapp Aではaセッションに保存し、webapp Bではセッションからを取得しaてAにキャストすると、ClassCastExceptionがスローされます。

これを解決する方法はありますか?

4

6 に答える 6

6

これを解決する方法はありますか?

基本的にいいえ。

JLSに関する限り、タイプは異なるタイプであり、JVMが別のふりをすることを許可する方法はありません. たとえば、クラスは異なるコードと異なるオブジェクト レイアウトを持つことができます。JVM をだまして型を同じものとして扱うことができれば、JVM ランタイムの安全性を吹き飛ばすことができます。その方法は狂気です。

解決策は、2 つの異なるクラス ローダーが同じクラスをロードしていないことを確認することです。Tomcat のコンテキストでは、これは、2 つ以上の Web アプリケーションがクラスのインスタンスを共有する必要がある場合、そのクラスを両方に共通のクラスローダーで定義する必要があることを意味します。たとえば、JAR ファイルを$CATALINA_HOME/libor$CATALINA_HOME/commonディレクトリに配置します。


クラスが異なるクラスローダーによってロードされなければならない技術的な理由がある場合(クラスが実際に異なるためなど)、クラスの両方のバージョンが実装するインターフェースを定義し、実装クラスではなくインターフェイス。もちろん、インターフェイスは共有クラスローダーによってロードされる必要があります...そうしないと、同じ問題が再び発生します。

于 2012-05-13T07:24:37.873 に答える
3

基本的に、この状況を回避する必要があります。両方の機能を同じ webapp に配置するか、クラス A を含むライブラリを適切な場所に移動して、1 つのクラスローダーのみが使用されるようにします。異なるクラスローダーによってロードされた 2 つのクラスは、JVM では完全に区別されます。それらの間でキャストすることはできません。

使用されるさまざまなクラスローダーの詳細については、 Tomcat クラスローダーのドキュメントを参照してください。この共通クラスを共通クラスローダー領域に入れたいようです。ドキュメントに記載されているように、これは非常に珍しいことですが、2 つの Web アプリケーション間でオブジェクトを本当に共有したい場合 (これもまた珍しいことです)、これがおそらく最も簡単な方法です。

于 2012-05-13T07:20:30.913 に答える
1

できません。異なるクラスローダーによってロードされる 2 つのクラスは異なります。

于 2012-05-13T08:23:18.940 に答える
0

クラスのパッケージ名と署名が同じであっても、異なるクラスから 2 つのオブジェクトをキャストすることはできませんが、apache bean utils ライブラリを使用するだけで、あるデータから別のオブジェクトにデータをコピーできます。BeanUtils.copyProperties(o1, o2);

于 2015-04-23T23:59:34.153 に答える
0

おそらく、共有オブジェクトをシリアル化できますか?

私は必ずしもこのアプローチを提唱しているわけではありませんが、シリアライゼーションが本質的に行うことです.JVMまたはClassLoader Xからシリアライズし、別のJVM / ClassLoader Yにロード(デシリアライズ)します...

于 2013-10-31T06:38:50.013 に答える