并发访问导致ClassCastException(X不能强制转换为X),或者JBoss中如何解决此类类加载问题
Posted
技术标签:
【中文标题】并发访问导致ClassCastException(X不能强制转换为X),或者JBoss中如何解决此类类加载问题【英文标题】:Concurrent access causes ClassCastException (X cannot be cast to X), or how to resolve such class loading problems in JBoss 【发布时间】:2011-07-07 07:19:42 【问题描述】:我有一个关于 JBoss 和类加载的问题。
这是我正在使用的配置。我在同一台服务器上有两个 JBoss 4.2.3.GA 实例。在每个实例上,一个应用程序正在运行,并且这些应用程序正在相互通信。有一个实用程序类,包含在两个应用程序档案中。此实用程序类在两个应用程序中完全相同。
这通常可以正常工作,但在特定情况下,我会得到 ClassCastException。案例如下:
一个用户正在使用一个 Web 应用程序,它在第一个 JBoss 实例上调用该应用程序(我们称它为应用程序 A)。并且应用程序 A 调用应用程序 B(在第二个实例上)。此特定调用需要几秒钟才能成功。
如果另一个用户试图在类似的上下文中使用 Web 应用程序(调用应用程序 A,它调用应用程序 B),并且如果此调用发生在第一个用户调用期间,我会系统地收到 ClassCastException:X cannot be cast to X
(其中 X 是我的实用程序类,由两个应用程序共享)。
我找到了一些信息,我推断这是一个类加载问题。实际上,在这种并发调用的特定上下文中,我的实用程序类不是由同一个类加载器加载的。我放了一个打印命令来查看使用了哪个类加载器。在通常的行为中,org.jboss.mx.loading.UnifiedClassLoader3 用于加载类。在上述特定情况下,应用程序 B 似乎为第二个用户使用了不同的类加载器。我的打印命令给了我以下信息:
WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/----------> Parent Classloader:java.net.FactoryURLClassLoader@de8209
我的猜测是应用程序 B 返回了一个由该 WebappClassLoader 加载的实用程序类的实例,而应用程序 A(使用 UnifiedClassLoader3)无法转换它。
但我不明白为什么在这种情况下不能在应用程序 B 上使用 UnifiedClassLoader3。为什么要使用这个 WebappClassLoader?
关于我的 JBoss 实例中的类加载配置,我只知道使用了类加载隔离,以下配置用于两个应用程序:
<jboss-app>
<module-order>strict</module-order>
<loader-repository>applicationAorApplicationB.ear</loader-repository>
</jboss-app>
您有什么建议可以解决这个问题吗?如何配置 jboss 类加载器以避免这些类转换异常?
我准确地说没有热部署:我每次部署应用程序时都会清理服务器。
【问题讨论】:
这类似于***.com/questions/14057932/… 【参考方案1】:如果 JBoss 对不同的包使用不同的类加载器,它实际上是按照规范遵循的行为。对于许多版本,它没有这样做。您可以禁用 WAR 类加载器隔离。请参阅JBoss documentation 了解更多信息。
您还可以使用各种不同的方法,这些方法不需要应用程序在同一个类加载器中进行通信,这将使您的应用程序更符合规范。详情请见this *** question。
【讨论】:
以上是关于并发访问导致ClassCastException(X不能强制转换为X),或者JBoss中如何解决此类类加载问题的主要内容,如果未能解决你的问题,请参考以下文章
MIUI 11/12 主题切换导致 LifeCycleException、ClassCastException
Java HashMap导致ClassCastException
dataset.collectAsList() 导致集群中的 java.lang.ClassCastException
List<T> 上的 UISelectMany 导致 java.lang.ClassCastException:java.lang.String 无法强制转换为 T