[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
Sun Dec 10 23:01:48 EST 2017


Hi Stuart,

Thanks for the reply.  A few followup questions if you don't mind.


>> 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.
>>
>
> Undertow returns a different facade for each request. Undertow uses its
> internal representation of a session (io.undertow.server.session.Session)
> that is stored in the session manager, and wraps a facade around it
> (io.undertow.servlet.spec.HttpSessionImpl) that implements Servlet
> semantics.
>

That's what I had assumed as well, based on the behaviour I had noticed.
Thanks for confirming.


>
>
>>
>> 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()
>>
>
> I guess this could be considered a bug in that isNew will not throw an
> IllegalStateException, which is the only place that the invalid flag is
> used without also consulting the underlying session, but you sound as if
> you expect the session to still work after it has been invalidated?
>

No - quite the opposite actually.  I'm expecting that all session objects
to react the same after it has been invalidated.  If I use one of the
facades from a prior request to invalidate the session, I would expect that
every facade would respect the same state.  For instance, if I do the
following:

Request 1:

// store a copy of the session object to be available in a later request
static Session cachedSessionObj = request.getSession();


Request 2:

// invalidate the session from the cached object
cachedSessoinObject.invalidate();

// get a new session
Session newSession = request.getSession();


I would expect that cachedSessionObj.getId() != newSessoin.getId().

However, the request.getSession() doesn't get a new session object.  Rather
it still returns the old (now invalidated) session object.  So any logic
that is dependent on having a fresh session object fails (since the session
object is returned is actually the invalidated session).



> There is no requirement that the same session is represented by a single
> java object, and especially it in a distributed environment this is not
> possible. Even though we could keep the same facade around for all requests
> this can encourage people to write apps that rely on this behaviour, and
> also increases the likelihood that the facade will become tenured and
> require a full GC to be reclaimed.
>

Understood.


>
>> 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.
>>
>
> This is a JVM bug. Which JVM are you using?
>
I'm running Oracle Hotspot Java 8x64 on a Windows platform (server 2016).
I've tried with both patch 131 and 151, and both exhibit the same
behaviour.

To implement this I would remove the WeakReference which will not work with
> Undertow's session management strategy, and instead register a listener to
> remove the session from the local map when it is invalidated. If you really
> want to access the underlying Undertow session you can
> call io.undertow.servlet.spec.HttpSessionImpl#getSession() to return the
> Underlying Undertow session, although it should not be necessary.
>

I've already removed the WeakReference as soon as I noticed that the
session facade returned by Undertow changed at each request.  I am using a
session listener to remove it from the local map when it is invalidated,
but I need an ability for an JMS listener to be able to invalidate a
session object based on an id it receives.

How can I access Undertow's SessionManager from within my application?  Is
there any way I can retrieve it from the CDI?  I tried adding
the io.undertow.core module to my jboss-deployment-structure.xml, but yet I
can't access it via injection or
via: CDI.current().getBeanManager().getBeans(SessionManager.class); in both
cases it is unable to find the SessionManager class.  Is there some other
way I can access it/retrieve it from within my application?


Thanks,

Eric





> 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
>>
>> _______________________________________________
>> wildfly-dev mailing list
>> wildfly-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/wildfly-dev/attachments/20171210/8de14ded/attachment-0001.html 


More information about the wildfly-dev mailing list