我有一个应用程序,它由EJB模块,Web模块和许多JAR(我自己的和第三方库)组成。它被打包为EAR文件。 libs位于“libs”目录中,EJB清单文件在其类路径中包含这些lib。打包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注释的方法中的一些缓存。为了满足Security模块,它首先在ActiveUser中的ThreadLocal上设置系统凭据。然后它调用注入的EJB上的一个方法,该方法返回缓存的数据(在检查ActiveUser上的凭据之后)
当我部署我的应用程序时(使用weblogic maven插件),一切都像魅力一样。
然后我重新部署我的应用程序(再次使用weblogic maven插件)。我已经阅读了WebLogic文档,并强调在重新部署时会丢弃旧的类加载器并实例化新的类加载器(因为无法卸载或更新类加载器加载的类)。但是我的重新部署失败了,因为当Web模块试图读取@PostConstruct中缓存的数据时,EJB抱怨用户没有经过正确的身份验证。
在调试代码之后,我发现Web模块bean仍然使用由“旧”类加载器加载的ActiveUser类定义(对象ID与旧类加载器的对象ID相同)。 EJB bean使用新类加载器加载的ActiveUser类定义。所以ThreadLocals当然不再是同一个对象了。我还想象由于这个特殊的状态,可能会引发一些ClassCastExceptions。
为什么这个旧的“鬼”类加载器仍然有效?我使用WLS-cat应用程序检查了我的应用程序的类加载器树,这里只有新的类加载器 - 没有旧的类加载器的痕迹。
有关行动方案的任何建议吗?有没有人经历过这个?
如果我重新启动我的托管服务器,应用程序启动没有任何问题,但我不想在每次重新部署后重新启动:我想每晚重新部署夜间快照构建并自动运行集成测试并且weblogic maven插件没有任何重启服务器的目标。