[wildfly-dev] request.getSession() returns a different object for each request - Undertow's session object is the object retrieved by request.getSession()
Eric B
ebenzacar at gmail.com
Fri Dec 8 23:04:11 EST 2017
I'm migrating a legacy (circa 2005) n-tier JBoss 4 application to run in
Wildfly 10. It was a struggle, but got pretty much everything done. We've
been trying as hard as possible not to refactor logic/code/etc except in
the cases where it is simply no longer compatible. The goal was to get the
application working "as-is" in WF, then start tackling the job of breaking
it apart and refactoring it into proper pieces.
The problem I have run into now is regarding session management. The
application was designed to run on multiple nodes, but in standalone
instances - ie: there is no shared memory, nor any distributed caches. So
I'm trying to get my WF10 application to follow the same pattern (even
though I realize all this exists in WF10 out of the box with
Infinispan/etc).
One of the requirements is to only have a single session active for a user
at any time in the "cluster". The JB4 application accomplished this by
maintaining a local cache (HashMap) of session objects keyed by username.
When a user logs into any node, a JMS message is broadcast to all the nodes
to invalidate any session belonging to that user. The listener on each
node then searches in his cache for a matching user/session object and does
a session.invalidate(). Some extra logic is used for WeakReferences for
the session objects (in case the session is destroyed by some other flow in
the container).
As ugly as the solution was, we've tried to follow the same pattern under
WF10. But this is failing in many different ways and reinforces my belief
that it isn't the right approach. However, I would like to understand
how/why this is failing.
My server configuration is using a <local-cache> for my "web" cache. So to
me this means it is only local to the machine. But:
1) on any specific node, request.getSession() returns a different object
for each request. The sessionId() remains the same, but the actual object
ID changes. This implies that it is a different representation of the
session object.
2) if I persist a local copy of the HttpSession object between requests
(ex: in a static map) and invalidate the session using the persisted
object, my request.getSession() object is not updated (ex: the invalid flag
is still set to false), but the session is dead. Trying to call
request.getSession().invalidate() throws IllegalStateException as do calls
to request.getSession().set/getAttribute()
3) over time, my JVM will actually crash with an EXCEPTION_ACCESS_VIOLATION
in a GC process. This always seems to correlate with a thread that is
trying to do some session invalidation via the persisted session copy.
Is anyone able to explain this behaviour? Why is the session object always
different between requests? Shouldn't it be the same request? What is
Undertow doing with the session objects between requests? Is the Undertow
object being passivated in some way and my attempt to invalidate if from
within my cached version causing this kind of access violation? Is my
cached object referencing memory that has been cleared by the GC (ex: does
the request.getSession() object only a WeakReference to the actual Undertow
object)?
Finally, what would the recommended approach be to doing something like
this? Using a distributed web-cache is unfortunately not an option at the
moment. So give that, is there some way to access the Undertow session
manager directly?
Thanks for any insight. I thought we had a functional solution but in
production (under real load), the intermittent JVM crashes are telling me
that our solution is broken.
Eric
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/wildfly-dev/attachments/20171208/529df183/attachment.html
More information about the wildfly-dev
mailing list