由于不同的类加载器,从同一个耳朵的两次不同战争中加载同一类时,发生ClassCastException

时间:2018-12-24 07:01:36

标签: java weblogic classloader oracle-adf ear

我正在开发一个现有的ADF应用程序,该应用程序在Weblogic上部署的EAR内部有两个不同的项目模块。
1.具有VO,EO和AM的模型项目(包含应用模块的实现)
2. UI项目(使用Model Project的构建文件为此项目创建了战争)

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

现在问题是使用

检索应用模块实现  ApplicationModuleHandle amHandle = Configuration.createRootApplicationModuleHandle("**.**.classpackage","config_name");

amImpl = (MyAMImpl) amHandle.useApplicationModule();

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

  

ClassCastException。

我的查询是,是否有任何方法可以使用weblogic-application.xml使用同一类加载器加载两次战争。或代码级别的任何其他配置。

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

我们非常感谢您的帮助。

编辑: 首先是另一个包含单例对象的模块。为了进一步清楚起见,是一个石英单例。 UI项目包含一个触发侦听器,该侦听器调用应用程序模块。

因此,在进行大量故障排除后,我找到了原因和解决方案。

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

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

P.S。 :我知道查询一开始并没有太多解释,因为我自己不确定原因。对此深表歉意。而且该应用程序具有明确的设计缺陷。它仍然有。希望有人觉得这有用

1 个答案:

答案 0 :(得分:0)

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

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

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