The call in JBossCacheManager.findSession(String id) to SessionReplicationContext.bindSession(...) only binds the session if ClusteredSessionValve has first called SessionReplicationContext.enterWebapp() to establish the context. The problem is, if any code calls Request.getSession(...) before ClusteredSessionValve is invoked, the session will be cached in the request, not bound to the context, and subsequent calls to Request.getSession(...) will use the cached session and never call JBossCacheManager.findSession(...). Result is the session will never be bound to the context and won't be replicated.
BatchReplicationClusteredSessionValve calls Request.getSession(...) before ClusteredSessionValve is invoked. SecurityAssocationValve happens to save us, by providentially calling Manager.findSession(...) after the request has passed through ClusteredSessionValve. But that's just good luck; we need to make sure the session is properly bound to the context.