java.lang.ClassCastException 的含义:someClass 与 someClass 不兼容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5352550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Meaning of java.lang.ClassCastException: someClass incompatible with someClass
提问by Frantisek Kossuth
I was experiencing occasional exceptions in XPages application:
我在 XPage 应用程序中偶尔遇到异常:
java.lang.ClassCastException: someClass incompatible with someClass.
Both mentioned classes are the same, it is class used as session bean. I was not able to google anything covering my problem. Usual explanation for this was change in design elements, not my case.
两个提到的类是相同的,它是用作会话 bean 的类。我无法用谷歌搜索涵盖我的问题的任何内容。对此的通常解释是设计元素的变化,而不是我的情况。
The XPage application become unusable (pages using session bean someClass) since that moment, until restart of http task, or resave of faces-config.xml.
从那一刻起,XPage 应用程序变得不可用(使用会话 bean someClass 的页面),直到重新启动 http 任务或重新保存 faces-config.xml。
In some cases this is related to other exception:
在某些情况下,这与其他异常有关:
com.ibm.jscript.InterpretException: Script interpreter error, line=x, col=y:
Java method 'method(signature containg someClass)'
on java class 'someOtherClass' not found
What is behind this behavior?
这种行为的背后是什么?
回答by Frantisek Kossuth
Philippe Riand explaned this by email:
Philippe Riand 通过电子邮件解释了这一点:
This class cast happens because the same class had been loaded twice by 2 different class loaders. Thus, from a Java standpoint, they are different and the cast fails.
Now, each XPages application is having its own classloader. But this class loader is discarded each time a design change happens to the application, through Domino Designer for example. This is required as a change to an XPages generates a new Java class that should then be loaded instead of the previous one. When this happens, the classloader is discarded and a new is created. Then all the application related classes are reloaded, as they are needed, even though they didn't change.This is a common behavior implemented by J2EE servers. That said, if your code is caching an object in a scope that is notdiscarded when a design change occurs, then this is likely to happen. For example, the applicationScope & sessionScope are currently not discarded when a design change happens, which might lead to this problem. This was a design choice as discarding the scopes sometimes provides a bad developer experience, but with this drawback.
Finally, saving faces-config.xml works as a workaround. When this file is saved, then the entire module is discarded from memory, including the scopes, This explains why it works. Making a change to your custom Java class should reload the module and remove the issue.
发生这种类转换是因为同一个类被 2 个不同的类加载器加载了两次。因此,从 Java 的角度来看,它们是不同的,并且转换失败。
现在,每个 XPage 应用程序都有自己的类加载器。但是每次应用程序发生设计更改时,都会丢弃此类加载器,例如通过 Domino Designer。这是必需的,因为对 XPage 的更改会生成一个新的 Java 类,然后应该加载该类而不是前一个类。发生这种情况时,类加载器将被丢弃并创建一个新的类加载器。然后所有与应用程序相关的类都会在需要时重新加载,即使它们没有改变。这是 J2EE 服务器实现的常见行为。也就是说,如果您的代码在不属于当发生设计更改时被丢弃,则很可能会发生这种情况。例如,applicationScope 和 sessionScope 当前在发生设计更改时不会被丢弃,这可能会导致此问题。这是一个设计选择,因为丢弃范围有时会提供糟糕的开发人员体验,但存在此缺点。
最后,保存 faces-config.xml 作为一种解决方法。当这个文件被保存时,整个模块都会从内存中被丢弃,包括范围,这解释了它为什么工作。对您的自定义 Java 类进行更改应该重新加载模块并消除问题。
So it seems putting beans (even indirectly) into sessionScope or applicationScope is the cause.
因此,似乎将 bean(甚至是间接地)放入 sessionScope 或 applicationScope 是原因。
回答by Ernest Friedman-Hill
If the same class file is loaded in different class loaders, the two resulting Java classes are notthe same class; you wouldn't be allowed to pass instances of one to functions expecting the other. Generally, if you're seeing this kind of problem, it's because you've got multiple child classloaders that can access a jar file that's not visible to their common parent classloader. You may need to move the jar containing "someclass" to a common library directory instead of (for example) a specific webapp directory.
如果在不同的类加载器中加载同一个类文件,则生成的两个Java类不是同一个类;你不会被允许将一个的实例传递给期望另一个的函数。通常,如果您看到此类问题,那是因为您有多个子类加载器可以访问其公共父类加载器不可见的 jar 文件。您可能需要将包含“someclass”的 jar 移动到公共库目录而不是(例如)特定的 webapp 目录。
回答by Prince
Just putting my experience over here.
只是把我的经验放在这里。
I was running my app on CAT environment with multiple JVMs when I came across this issue. Because the same build was running successfully for me on ITG environment, I restarted both the JVMs on CAT and the error was resolved. Not exactly sure what was causing it.
当我遇到这个问题时,我正在具有多个 JVM 的 CAT 环境中运行我的应用程序。因为在 ITG 环境中为我成功运行了相同的构建,所以我在 CAT 上重新启动了两个 JVM,错误得到了解决。不完全确定是什么原因造成的。
回答by Javi
Cleaning the project also make this works!
清理项目也可以使它起作用!