在两个类完全相同的情况下获得类转换exception
我正在做一个JBoss SEAM项目,当我查看一个表单时,我得到这个错误。
java.lang.ClassCastException: it.cogitoweb.csi.entity.csiorelav.CsiTipoLav cannot be cast to it.cogitoweb.csi.entity.csiorelav.CsiTipoLav
它总是和屏幕上显示的窗体相关的JPA类相同,对我来说没有意义,为什么它是同一个类,这似乎是不可能的。
当两个不同的ClassLoader
对象加载具有相同名称的类时会发生这种情况。 Java中两个类的相等取决于完全限定的名称和加载它的类加载器。
所以,如果两个独立的类加载器从同一个位置加载类,那么这些types的对象将不能被转换为其他types,即使它们的类被调用相同。
这是因为这个类已经被两个不同的类加载器加载了。 你不能在他们之间施放。
您可能在应用程序中获得了CsiTipoLav
副本,并且这两个不同的副本将在不同的时间从不同的类加载器加载。 JBoss在层次结构中有许多不同的类加载器,很容易让事情变得复杂。
确保你只有一个class的副本。
正如Joachim先前解释的那样,当两个类加载器加载具有相同名称的类时,通常会发生java.lang.ClassCastException。 但是,当发生这种情况时,我遇到了另一种情况。
这可能会发生在一些IDE自动重新加载已修改的类。 在这种情况下,可能会在内存中保留导致ClassCastException的旧版本的类。
以下是可以解决此问题的几种方法:
-
如果您正在编写自定义类加载器,则在加载类时请确保基类/默认类加载器尚未加载该类的实例。
-
使该类被加载为已由默认类加载器加载的类的子类。
-
使正在加载的类实现一个已经由默认类加载器加载的接口。
您正在尝试投射的对象由不同的类加载器加载,而不是加载了要尝试投射的类的加载器。
在我的情况下,我有两个不同的* .ear,并想从另一个加载类。 所以我不得不隔离类加载器。 我用这个描述:
http://www.thorgull.be/wiki/index.php?title=ClassLoader_isolation_in_JBOSS
它为我工作。