Fra*_*uth 13 java classcastexception lotus-domino xpages
我在XPage应用程序中经常遇到异常:
java.lang.ClassCastException: someClass incompatible with someClass.
Run Code Online (Sandbox Code Playgroud)
两个提到的类都是相同的,它是用作会话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
Run Code Online (Sandbox Code Playgroud)
这种行为的背后是什么?
Fra*_*uth 15
Philippe Riand通过电子邮件解释了这一点:
发生此类强制转换是因为同一个类已被两个不同的类加载器加载两次.因此,从Java的角度来看,它们是不同的,并且转换失败.
现在,每个XPages应用程序都有自己的类加载器.但是,每次通过Domino Designer进行设计更改时,都会丢弃此类加载器.这是必需的,因为对XPages的更改会生成一个新的Java类,然后应该加载而不是前一个.发生这种情况时,将丢弃类加载器并创建一个新的.然后,所有与应用程序相关的类都会在需要时重新加载,即使它们没有更改.这是J2EE服务器实现的常见行为.也就是说,如果您的代码正在缓存范围中的对象,而该范围在设计更改发生时未被丢弃,则可能会发生这种情况.例如,当设计更改发生时,当前不会丢弃applicationScope和sessionScope,这可能会导致此问题.这是一种设计选择,因为丢弃范围有时会提供糟糕的开发人员体验,但有这个缺点.
最后,保存faces-config.xml可以解决此问题.保存此文件后,整个模块将从内存中丢弃,包括范围,这就解释了它的工作原理.对自定义Java类进行更改应重新加载模块并删除该问题.
因此,似乎将bean(甚至间接)放入sessionScope或applicationScope是原因.
如果在不同的类加载器中加载相同的类文件,则两个生成的Java类不是同一个类; 你不会被允许将一个实例传递给期望另一个的函数.通常,如果您遇到这种问题,那是因为您有多个子类加载器可以访问其公共父类加载器不可见的jar文件.您可能需要将包含"someclass"的jar移动到公共库目录而不是(例如)特定的webapp目录.