OpenLiberty中Session Scope CDI Bean与session-cache特性的异常行为排查
问题分析:OpenLiberty中Session Scope CDI Bean结合Hazelcast session-cache的异常行为
异常现象
在OpenLiberty中使用Session Scope的CDI Bean结合Hazelcast作为提供方的session-cache特性时,出现如下异常:修改Bean属性后,若在同一方法内调用session.getAttributeNames(),共享会话缓存不会更新;但不调用该方法时,缓存更新正常。
相关代码与配置
TestBean代码
@SessionScoped @Named("test") public class TestBean { private String test = "init"; public String process(HttpServletRequest request) { test = request.getParameter("test"); HttpSession session = request.getSession(true); session.getAttributeNames(); // 此处省略返回逻辑 } }
server.xml配置
<server description="Liberty Server for Sessions Management"> <featureManager> <feature>servlet-6.0</feature> <feature>sessionCache-1.0</feature> <feature>cdi-4.0</feature> <feature>pages-3.1</feature> <feature>mpConfig-3.1</feature> </featureManager> <variable name="http.port" defaultValue="9090"/> <variable name="https.port" defaultValue="9453"/> <variable name="app.context.root" defaultValue="test"/> <httpEndpoint httpPort="${http.port}" httpsPort="${https.port}" id="defaultHttpEndpoint" host="*" /> <httpSessionCache libraryRef="jCacheVendorLib" uri="file:${server.config.dir}/hazelcast-config.xml" writeContents=ALL_SESSION_ATTRIBUTES > </httpSessionCache> <library id="jCacheVendorLib"> <file name="${shared.resource.dir}/hazelcast-5.3.6.jar" /> </library> <webApplication location="test.war" contextRoot="${app.context.root}" /> </server>
可能原因分析
- CDI Session Bean的延迟持久化机制:OpenLiberty中,Session Scope的CDI Bean默认采用延迟写入策略,容器会在请求处理的后期(如请求结束阶段)才将Bean的变更序列化并同步到Hazelcast缓存。而调用
session.getAttributeNames()会提前触发会话的序列化/同步流程,此时Bean的属性修改还未被容器捕获,导致缓存中保存的仍是修改前的状态。 - 会话访问触发的缓存同步优先级:调用
session.getAttributeNames()时,session-cache模块会触发一次会话状态的快照操作,该操作会优先将当前内存中未更新的会话状态同步到缓存,后续CDI Bean的变更因为已错过这次同步时机,无法被写入缓存。 - writeContents配置的触发时机冲突:配置中
writeContents=ALL_SESSION_ATTRIBUTES会要求全量写入会话属性,但写入动作的触发依赖于容器的生命周期事件。session.getAttributeNames()提前触发了会话的序列化周期,此时CDI Bean的变更尚未被标记为需要持久化的状态,因此缓存未得到更新。
内容的提问来源于stack exchange,提问作者Rafik
相关产品推荐
相关产品推荐

