Expand my Community achievements bar.

Invalid session in FlexSessionListener.sessionDestroyed

Avatar

Level 1
I'm implementing a FlexSessionListener like:



public void sessionDestroyed(FlexSession flexSession) {

if (LOG.isInfoEnabled()) {

LOG.info("Flex session destroyed: " + flexSession

+ " - "

+ flexSession.getUserPrincipal());

}

unregisterSessions(flexSession); // accesses session
attribute

try {

flexSession.removeSessionDestroyedListener(this);

}

catch (LocalizedException e) {

LOG.warn("Error during sessionDestroyed for " + flexSession,
e);

}

}





Using the flexSession parameter causes exceptions, which is
surprising at best.



Accessing a session attribute causes this:



flex.messaging.LocalizedException: The FlexSession is
invalid.

at
flex.messaging.FlexSession.checkValid(FlexSession.java:515)

at
flex.messaging.FlexSession.getAttribute(FlexSession.java:269)

at
com.acesis.security.SessionRegistry.unregisterSessions(SessionRegistry.java:492)

at
com.acesis.security.SessionRegistry.sessionDestroyed(SessionRegistry.java:345)

at flex.messaging.FlexSession.destroy(FlexSession.java:250)

at
flex.messaging.endpoints.rtmp.RTMPFlexSession.close(RTMPFlexSession.java:42)

at
flex.messaging.endpoints.rtmp.NIORTMPConnection.invalidateFlexSession(NIORTMPConnection.java:221)

at
flex.messaging.endpoints.rtmp.RTMPFlexSession.invalidate(RTMPFlexSession.java:47)

at
flex.messaging.security.LoginManager.logout(LoginManager.java:192)

at
flex.messaging.services.AuthenticationService.serviceCommand(AuthenticationService.java:65)

at
flex.messaging.MessageBroker.routeCommandToService(MessageBroker.java:622)

at
flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:298)

at
flex.messaging.endpoints.rtmp.AbstractRTMPServer.dispatchMessage(AbstractRTMPServer.java:682)

at
flex.messaging.endpoints.rtmp.NIORTMPConnection$RTMPReader.run(NIORTMPConnection.java:665)

at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:643)

at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:668)

at java.lang.Thread.run(Thread.java:595)





Removing the FlexSessionListener causes this:



flex.messaging.LocalizedException: The FlexSession is
invalid.

at
flex.messaging.FlexSession.checkValid(FlexSession.java:515)

at
flex.messaging.FlexSession.removeSessionDestroyedListener(FlexSession.java:372)

at
com.acesis.security.SessionRegistry.sessionDestroyed(SessionRegistry.java:347)

at flex.messaging.FlexSession.destroy(FlexSession.java:250)

at
flex.messaging.endpoints.rtmp.RTMPFlexSession.close(RTMPFlexSession.java:42)

at
flex.messaging.endpoints.rtmp.NIORTMPConnection.invalidateFlexSession(NIORTMPConnection.java:221)

at
flex.messaging.endpoints.rtmp.RTMPFlexSession.invalidate(RTMPFlexSession.java:47)

at
flex.messaging.security.LoginManager.logout(LoginManager.java:192)

at
flex.messaging.services.AuthenticationService.serviceCommand(AuthenticationService.java:65)

at
flex.messaging.MessageBroker.routeCommandToService(MessageBroker.java:622)

at
flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:298)

at
flex.messaging.endpoints.rtmp.AbstractRTMPServer.dispatchMessage(AbstractRTMPServer.java:682)

at
flex.messaging.endpoints.rtmp.NIORTMPConnection$RTMPReader.run(NIORTMPConnection.java:665)

at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:643)

at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:668)

at java.lang.Thread.run(Thread.java:595)





The FDS documentation doesn't specify that you cannot do
anything with the flexSession in a sessionDestroyed call.
The same code has worked, IIRC, in GMC 4. It seems that the
behavior changed in GMC 5 or 6. I'm running the released bits now.



Is this the intended behavior?

--

Jürgen Failenschmid

6 Replies

Avatar

Level 3
In the SessionDestroyED event, it is not possible to get
attribute. Thanks for bring out the doc issue. The way which I
overcome this issue I have to have a map to store the information
for the destroy into the sessionID

public void sessionDestroyed(FlexSession flexSession) {

String signoffUserName = (String)
sessionPlayerMap.remove(flexSession.getId());

}



William Chan

Avatar

Former Community Member
That kind of defeats the purpose of being able to store
attributes in the

Flex session instance. Actually, I did that before FDS
supported custom

session attributes.



Attributes aside, it is strange that the session lifecycle
listener cannot

be unregistered.



--

J�rgen Failenschmid





Avatar

Level 3
Hi Jürgen,



The behavior for session destruction notification matches the
behavior defined by the Servlet spec and its HttpSessionListener
interface. The behavior is to notify session destroy listeners
after all attributes have been unbound from the session and the
session have been invalidated. My opinion is that the destory
listener hook as spec'ed isn't very useful (I'd have voted for
pre/post hooks).



If you want to do something on session shutdown, the safer
approach is to create an instance of a class that implements the
FlexSessionBindingListener interface on session creation and add it
as an attribute on the new session. As long as no code removes this
attribute from the session arbitrarily, when the session is
destroyed this attribute will be unbound and its valueUnbound()
callback will be invoked. You shouldn't base your logic in
valueUnbound() on having access to attributes in the session,
because other attributes may be unbound by the time your listener
is unbound.



Best,

Seth

Avatar

Former Community Member
I hear you. I am trying to use the attribute lifecycle
notifications rather

than the session lifecycle ones. It looks like it is a
feasible workaround

for what I need at this point.



It still doesn't solve the exception when trying to
unregister the session

listener. That needs to be fixed in an updater.



Also, I trust that Adobe will reconsider the usefulness of
the session

lifecycle notifications...



Thanks,

--

J�rgen Failenschmid





Avatar

Level 3
Hi Jürgen,



I've logged a bug for the exception when you attempt to
unregister a session destroy listener from an invalidated flex
session.



I've also logged an enhancement request to implement a
pre-destroy listener hook. The problem with that is that we're
still stuck with the servlet spec, so while we could do this for
RTMP based sessions, in the Http case we wrap the underlying app
server's HttpSession and they don't give us a standard way to catch
or fire a pre-destroy hook if it's possible at all.



Thanks for your feedback.

Best,

Seth