java.lang.ClassCastException的含义:someClass与someClass不兼容

我在XPage应用程序中经常遇到exception:

java.lang.ClassCastException: someClass incompatible with someClass. 

两个提到的类都是相同的,它是用作会话bean的类。 我无法谷歌任何覆盖我的问题。 对此的通常解释是设计元素的变化,而不是我的情况。

从那时起,直到重启http任务或重新保存faces-config.xml,XPage应用程序变得不可用(使用会话bean someClass的页面)。

在某些情况下,这与其他例外有关:

 com.ibm.jscript.InterpretException: Script interpreter error, line=x, col=y: Java method 'method(signature containg someClass)' on java class 'someOtherClass' not found 

这种行为的背后是什么?

Philippe Riand通过电子邮件解释了这一点:

发生此类强制转换是因为同一个类已被两个不同的类加载器加载两次。 因此,从Java的角度来看,它们是不同的,并且转换失败。

现在,每个XPage应用程序都有自己的类加载器。 但是,每次通过Domino Designer进行设计更改时,都会丢弃此类加载器。 这是必需的,因为对XPages的更改会生成一个新的Java类,然后应该加载而不是之前的Java类。 发生这种情况时,将丢弃类加载器并创建一个新的。 然后,所有与应用程序相关的类都会在需要时重新加载,即使它们没有更改。这是J2EE服务器实现的常见行为。 也就是说,如果您的代码正在缓存范围中的对象,而该范围在设计更改发生时未被丢弃,则可能会发生这种情况。 例如,当设计更改发生时,applicationScope和sessionScope当前不会被丢弃,这可能会导致此问题。 这是一个设计选择,因为丢弃范围有时会提供糟糕的开发人员体验,但有这个缺点。

最后,保存faces-config.xml可以解决此问题。 保存此文件后,整个模块将从内存中丢弃,包括范围,这就解释了它的工作原理。 更改自定义Java类应重新加载模块并删除问题。

因此,似乎将bean(甚至间接)放入sessionScope或applicationScope是原因。

如果在不同的类加载器中加载相同的类文件,则两个生成的Java类不是同一个类; 你不会被允许将一个实例传递给期望另一个的函数。 通常,如果您遇到这种问题,那是因为您有多个子类加载器可以访问其公共父类加载器不可见的jar文件。 您可能需要将包含“someclass”的jar移动到公共库目录而不是(例如)特定的webapp目录。

把我的经验放在这里。

当我遇到这个问题时,我在带有多个JVM的CAT环境中运行我的应用程序。 因为在ITG环境中为我成功运行了相同的构建,所以我重新启动了CAT上的两个JVM并且错误已得到解决。 不完全确定导致它的原因。

清洁项目也使这个工作!