gpt4 book ai didi

java - 由于不同的类加载器,在同一个耳朵中从两个不同的 war 中加载相同的类时出现 ClassCastException

转载 作者:太空宇宙 更新时间:2023-11-04 09:57:42 24 4
gpt4 key购买 nike

我正在开发一个现有的 ADF 应用程序,其中部署在 weblogic 上的 EAR 中有两个不同的项目模块。
1. 具有 VO、EO 和 AM 的模型项目(包含应用模块实现)
2. UI项目(使用模型项目的构建文件为此项目创建war)

我添加了另一个 war 文件,用于与 UI 一起启用休息服务。不同 war 的原因是 UI war 需要 Web 身份验证,而我们希望通过提供多 token 身份验证来绕过 Rest war 。所以现在我们有两场 war 和三个模块。
1. 样板工程
2.UI项目
3. Rest 项目(使用 UI 项目和 Model 项目中的构建文件)

现在的问题是应用程序模块实现是使用

检索的 ApplicationModuleHandle amHandle = Configuration.createRootApplicationModuleHandle("**.**.classpackage","config_name");

amImpl = (MyAMImpl) amHandle.useApplicationModule();

如果其中一场 war 创建了我的 MyAMImpl 对象,另一场 war 则获得

ClassCastException.

我的问题是是否有任何方法可以使用weblogic-application.xml使用相同的类加载器来加载这两个 war 。或代码级别的任何其他配置。

附注:我避免使用自定义类加载器弄乱我的代码,或者在应用程序代码中强制使用相同的类加载器,因为它是现有应用程序。

非常感谢任何帮助。

编辑:首先有另一个包含单例对象的模块。为了进一步清晰起见,这是一个 Quartz Singleton。 UI 项目包含一个调用应用程序模块的触发器监听器。

因此,我通过大量故障排除找到了原因和解决方案。

原因:两次 war 都使用单独的类加载器,并且会创建不同的 Quartz Singleton 实例。每个也都有自己的 TriggerListener 实例。
因此,当其中一个模块调用 QuartzScheduler 和 Trigger Listener 时,它会创建一个应用程序模块(该模块持久化在应用程序中,不会被释放)。
现在,当第二个应用程序调用 QuartzSingleton 时,将为第二个类加载器创建相同的新实例和触发监听器,但返回应用程序模块的相同实例。由于第二个类加载器不知道返回的应用程序模块,因此它会抛出 ClassCastException。

解决方案:在 EAR 级别添加包含 Quartz Scheduler 的项目,并在 war 项目中添加该项目的构建输出(这样它们就不会抛出编译时异常)。这将使整个应用程序能够使用应用程序的类加载器(实际上是两场 war 的父类加载器)拥有一个 Quartz Scheduler Singleton 实例。这使得两个 war 都能够在父类加载器中找到该类,并且不会抛出异常,因为现在所有三个实例,即 Quartz Scheduler Singleton、TriggerListener 和 Application Module 都驻留在同一个类加载器中。

附注:我知道一开始并没有太多解释,因为我自己也不确定原因。对此表示诚挚的歉意。该应用程序存在明显的设计缺陷。但它仍然有。希望有人觉得这很有用

最佳答案

我也在查询中添加了原因和解决方案。

原因:两次 war 都使用单独的类加载器,并且会创建不同的 Quartz Singleton 实例。每个也都有自己的 TriggerListener 实例。因此,当其中一个模块调用 QuartzScheduler 和 Trigger Listener 时,它会创建一个应用程序模块(该模块保留在应用程序中并且不会被释放)。现在,当第二个应用程序调用 QuartzSingleton 时,将为第二个类加载器创建相同的新实例和触发监听器,但将返回应用程序模块的相同实例。由于第二个类加载器不知道返回的应用程序模块,因此它会抛出 ClassCastException。

解决方案:在 EAR 级别添加包含 Quartz Scheduler 的项目,并在 war 项目中添加该项目的构建输出(这样它们就不会抛出编译时异常)。这将使整个应用程序能够使用应用程序的类加载器(实际上是两场 war 的父类加载器)拥有一个 Quartz Scheduler Singleton 实例。这使得两个 war 都能够在父类加载器中找到该类,并且不会抛出异常,因为现在所有三个实例,即 Quartz Scheduler Singleton、TriggerListener 和 Application Module 都驻留在同一个类加载器中。

关于java - 由于不同的类加载器,在同一个耳朵中从两个不同的 war 中加载相同的类时出现 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53910219/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com