2

我有一个应用程序,它由一个 EJB 模块、一个 Web 模块和一些 JAR(我自己的和第三方的库)组成。它被打包为 EAR 文件。这些库位于“libs”目录中,EJB 清单文件在其类路径中包含这些库。打包 Web 模块时不包含依赖项或指定类路径。

The EAR content (simplified):
/libs/model.jar
/libs/other.jar
ejb.jar
web.war

我的 Web 模块中有一个 @Stateless bean,它通过注入 @EJB 从 EJB 模块中查找一个 bean。安全性是通过model.jar 中ActiveUser 类上的ThreadLocal 访问和检查用户角色来实现的。我的@stateless web bean 在一个用@PostConstruct 注释的方法中初始化了一些缓存。为了满足安全模块,它首先在 ActiveUser 中的 ThreadLocal 上设置系统凭据。然后它在注入的 EJB 上调用一个方法,该方法返回缓存的数据(在检查 ActiveUser 上的凭据之后)

当我部署我的应用程序(使用 weblogic maven 插件)时,一切都像一个魅力。

然后我重新部署我的应用程序(再次使用 weblogic maven 插件)。我已经阅读了 WebLogic 文档,这里强调在重新部署时旧的类加载器将被丢弃并实例化新的类加载器(因为无法卸载或更新由类加载器加载的类)。但是我的重新部署失败了,因为 EJB 抱怨当 Web 模块尝试读取 @PostConstruct 中缓存的数据时,用户没有得到正确的身份验证。

调试代码后,我发现Web模块bean仍然使用“旧”类加载器加载的ActiveUser类定义(对象ID与旧类加载器相同)。EJB bean 使用由新类加载器加载的 ActiveUser 类定义。所以 ThreadLocals 当然不再是同一个对象了。我还想象由于这种特定状态,可能会引发许多 ClassCastExceptions。

为什么这个旧的“幽灵”类加载器仍然活跃?我使用 WLS-cat 应用程序检查了我的应用程序的类加载器树,这里只有新的类加载器 - 没有旧类加载器的踪迹。

对行动方案有什么建议吗?有没有人经历过这个?

如果我重新启动托管服务器,应用程序启动时没有任何问题,但我不想在每次重新部署后重新启动:我想每晚重新部署夜间快照构建并自动运行集成测试,而 weblogic maven 插件没有任何目标重新启动服务器。

4

0 回答 0