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

我在XPages应用程序中偶尔遇到异常:

java.lang.ClassCastException: someClass incompatible with someClass.

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

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

在某些情况下,这与其他异常有关:

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

这种行为的背后是什么?


答案 1

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

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

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

最后,保存 face-config.xml可以作为解决方法。保存此文件后,整个模块将从内存中丢弃,包括作用域,这解释了它的工作原理。对自定义 Java 类进行更改应重新加载模块并消除该问题。

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


答案 2

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


推荐