2つの異なるWebアプリがあり、それぞれが異なるクラスローダーで同じクラスAをロードします。1つのインスタンスをセッションに配置し、それを他のWebアプリから取得すると、aClassCastException
がスローされます。
たとえば、webapp Aではa
セッションに保存し、webapp Bではセッションからを取得しa
てAにキャストすると、ClassCastException
がスローされます。
これを解決する方法はありますか?
2つの異なるWebアプリがあり、それぞれが異なるクラスローダーで同じクラスAをロードします。1つのインスタンスをセッションに配置し、それを他のWebアプリから取得すると、aClassCastException
がスローされます。
たとえば、webapp Aではa
セッションに保存し、webapp Bではセッションからを取得しa
てAにキャストすると、ClassCastException
がスローされます。
これを解決する方法はありますか?
これを解決する方法はありますか?
基本的にいいえ。
JLSに関する限り、タイプは異なるタイプであり、JVMが別のふりをすることを許可する方法はありません. たとえば、クラスは異なるコードと異なるオブジェクト レイアウトを持つことができます。JVM をだまして型を同じものとして扱うことができれば、JVM ランタイムの安全性を吹き飛ばすことができます。その方法は狂気です。
解決策は、2 つの異なるクラス ローダーが同じクラスをロードしていないことを確認することです。Tomcat のコンテキストでは、これは、2 つ以上の Web アプリケーションがクラスのインスタンスを共有する必要がある場合、そのクラスを両方に共通のクラスローダーで定義する必要があることを意味します。たとえば、JAR ファイルを$CATALINA_HOME/lib
or$CATALINA_HOME/common
ディレクトリに配置します。
クラスが異なるクラスローダーによってロードされなければならない技術的な理由がある場合(クラスが実際に異なるためなど)、クラスの両方のバージョンが実装するインターフェースを定義し、実装クラスではなくインターフェイス。もちろん、インターフェイスは共有クラスローダーによってロードされる必要があります...そうしないと、同じ問題が再び発生します。
基本的に、この状況を回避する必要があります。両方の機能を同じ webapp に配置するか、クラス A を含むライブラリを適切な場所に移動して、1 つのクラスローダーのみが使用されるようにします。異なるクラスローダーによってロードされた 2 つのクラスは、JVM では完全に区別されます。それらの間でキャストすることはできません。
使用されるさまざまなクラスローダーの詳細については、 Tomcat クラスローダーのドキュメントを参照してください。この共通クラスを共通クラスローダー領域に入れたいようです。ドキュメントに記載されているように、これは非常に珍しいことですが、2 つの Web アプリケーション間でオブジェクトを本当に共有したい場合 (これもまた珍しいことです)、これがおそらく最も簡単な方法です。
できません。異なるクラスローダーによってロードされる 2 つのクラスは異なります。
クラスのパッケージ名と署名が同じであっても、異なるクラスから 2 つのオブジェクトをキャストすることはできませんが、apache bean utils ライブラリを使用するだけで、あるデータから別のオブジェクトにデータをコピーできます。BeanUtils.copyProperties(o1, o2);
おそらく、共有オブジェクトをシリアル化できますか?
私は必ずしもこのアプローチを提唱しているわけではありませんが、シリアライゼーションが本質的に行うことです.JVMまたはClassLoader Xからシリアライズし、別のJVM / ClassLoader Yにロード(デシリアライズ)します...