web-dev-qa-db-ja.com

両方のクラスがまったく同じである場合にクラスキャスト例外を取得する

JBoss SEAMプロジェクトを実行していますが、フォームを表示するとこのエラーが発生します。

Java.lang.ClassCastException:
it.cogitoweb.csi.entity.csiorelav.CsiTipoLav cannot be cast to
it.cogitoweb.csi.entity.csiorelav.CsiTipoLav

画面に表示されるフォームに関連するJPAクラスは常に同じですが、なぜ同じクラスなのかはわかりません。不可能に思えます。

21
Phil

これは、2つの異なるClassLoaderオブジェクトが同じ名前のクラスをロードするときに発生します。 Javaの2つのクラスが等しいかどうかは、完全修飾名に依存しますおよびそれをロードしたクラスローダー。

したがって、2つの独立したクラスローダーが同じ場所からクラスをロードする場合、それらのクラスが同じと呼ばれていても、それらのタイプのオブジェクトを相互にキャストすることはできません。

38
Joachim Sauer

Joachimが以前に説明したように、Java.lang.ClassCastExceptionは通常、2つのクラスローダーが同じ名前のクラスをロードするときに発生します。しかし、これが発生する可能性がある別の状況に遭遇しました。

これは、変更されたクラスを自動的に再ロードする一部のIDEで発生する可能性があります。このような場合、ClassCastExceptionの原因となる古いバージョンのクラスがメモリに保持されている可能性があります。

この問題を解決する方法はいくつかあります。

  1. カスタムクラスローダーを作成している場合は、クラスのロード中に、基本/デフォルトのクラスローダーにそのクラスのインスタンスがまだロードされていないことを確認してください。

  2. ロードされるクラスを、デフォルトのクラスローダーによってすでにロードされているクラスのサブクラスにします。

  3. ロードされるクラスに、デフォルトのクラスローダーによってすでにロードされているインターフェースを実装させます。

詳細はこちら- http://www.jspwiki.org/wiki/A2AClassCastException

8
shaktimaan

これは、クラスが2つの異なるクラスローダーによってロードされているためです。それらの間でキャストすることはできません。

アプリケーションにCsiTipoLavの複製コピーがあり、2つの異なるコピーが異なるクラスローダーから異なる時間にロードされている可能性があります。 JBossには階層内に多数の異なるクラスローダーがあり、ひねりを加えるのは簡単です。

クラスのコピーが1つしかないことを確認してください。

5
skaffman

私の場合、2つの異なる* .earがあり、もう一方からクラスをロードしたいと思いました。そのため、クラスローダーを分離する必要がありました。私はこの説明を使用しました:

http://www.thorgull.be/wiki/index.php?title=ClassLoader_isolation_in_JBOSS

それは私のために働いた。

2
Patrick P

キャストしようとしているオブジェクトは、キャストしようとしているクラスをロードしたクラスローダーとは異なるクラスローダーによってロードされます。