I'm using Seam and a Seam app depends upon the Seam application being initialized before you can do much of anything in Seam. That said Seam puts some hooks into the sessionDidActivate() and sessionDidPassivate() events. Because of that when I start up my app I'm getting a Seam IllegalStateException because the contextInitialized() event is fired after sessionDidActivate() so Seam is not yet initialized it's Session hooks are being fired. What makes me think this is a bug is that sessionWillPassivate() is being correctly called before contextDestroyed() so it would seem that sessionDidActivate() being called before contextInitialized() would be inconsistent behavior. So to sum up I think tomcat should fire context and session events in the following order: contextInitialized sessionDidActivate sessionWillPassivate contextDestroyed As a side note Tomcat 5 follows what I think is the completely wrong but consistent order by firing events in this order: sessionDidActivate contextInitialized contextDestroyed sessionWillPassivate
Here is a link to the Seam Issue: http://jira.jboss.com/jira/browse/JBSEAM-1681
According to the servlet spec, the listeners are supposed to be called in the order that they're declared in web.xml. Except at shutdown the session listeners are supposed to be called before the context listeners. So the question is, how are the listeners declared in web.xml? (I don't know anything about how Seam integrates with Tomcat, but I guess there must be a deployment descriptor somewhere with the <listener> declarations.)
> According to the servlet spec, the listeners are supposed to be called in the > order that they're declared in web.xml. Except at shutdown the session listeners > are supposed to be called before the context listeners. > > So the question is, how are the listeners declared in web.xml? > > (I don't know anything about how Seam integrates with Tomcat, but I guess there > must be a deployment descriptor somewhere with the <listener> declarations.) Yes, Seam has a listener. And at shutdown in Tomcat 6 the Session Listeners are correctly called before the Servlet Listeners. The problem is that at server 'startup' the session listeners are also called before the Servlet Listeners which is causing trouble for Seam since Seam needs contextInitialized() to be called before sessionDidActivate(). Mike
You missed my point. The order in which the listeners are called depends (in part) on the order in which they are declared. The behaviour that you describe could be perfectly correct according to the servlet spec, *depending on how the listeners are declared*. For more details, see section 10.3.3 and 10.3.4 of the servlet specification. Here is a concrete example. Suppose web.xml contains these declarations: <listener> <listener-class>com.example.MySessionListener</listener-class> </listener> <listener> <listener-class>com.example.MyContextListener</listener-class> </listener> In this example, on startup the session listener will be called before the context listener (according to section 10.3.3 of the servlet spec). On shutdown, the session listener will again be called before the context listener (according to section 10.3.4). Another possibility is that a single listener class implements two listener interfaces. In that case, the spec doesn't say what order they should be called on startup. I guess if the listeners need to be called in a certain order, they need to be implemented in separate classes so that you can specify the order. So, how are the listeners declared in your case? Please post the contents of web.xml, or just the part with the <listener> declarations.
I see the confusion. When I say Session Listener I was talking about a class that implements HttpSessionActivationListener where you were thinking I meant an HttpSessionListener. When HttpSessionActivationListeners are not declared in the web.xml but are automatically called by the container when the instance passivates and activates instances stored in the Session. So what I'm saying is that I would expect the ServletContextListener.contextInitialized() to be called before HttpSessionActivationListener.sessionDidActivate(). When shutting down ServletContextListener.contextDestroyed() is currently correctly called after HttpSessionActivationListener.sessionWillPassivate(). Does that clear things up?
Sorry, you're right, I forgot about HttpSessionActivationListener objects being stored in the session itself. As far as I can see, the spec doesn't say what order these events are fired relative to the other types of events. Your idea that contextInitialized should come before sessionDidActivate sounds reasonable, but you may be stuck in the trap of "Tomcat follows the spec so it doesn't need to be fixed."
Ya, that's the trap I'm afraid of. :) I'm hoping that because it is a Seam problem perhaps Jboss might be able to assert some of their influence over tomcat to get them to fix it....but I guess we'll see. Thanks for looking at the issue.
I really vote for this. My own web application needs the same functionality. I use a spring WebApplicationContext and some of my Session Vales need beans from this context. So I store them transient in the session values and fetch them at sessionDidActivate. But I can not do this if my context is not up and running.
Looking at this now... Even with the latest spec things are not explicit and could be read either way. However, 1) I agree with the assessment that logically you would expect the context to be present before the sessions are activated 2) and the last paragraph SRV.16.1.7 hints in this direction as well. I'll see how easy it is to make the change.
See also bug 30344.
I have committed a fix to trunk. Initial testing looks OK but I will eave it a few weeks to see if any issues arise before proposing it for 6.0.x
Thanks tons for taking this on Mark. Mike
This is now proposed for 6.0.x
This has been committed to 6.0.x and will be in 6.0.17 onwards.