Stateful Webservice Session management issue
christiankerl May 10, 2010 11:20 PMHello everybody,
I'm building a webapp with Seam and I want to provide a webservice. Multiple requests to the webservice should be inside one HttpSession so I can maintain state in a session scoped bean.
I created the Webservice how it is described in the documentation chapter 24 (with standard-jaxws-endpoint-config.xml and stateless bean annotated with @WebService).
There is no problem until it comes to ending the session. The destroy method (annotated with @Destroy and @Remove) of my stateful session bean never gets called and the org.jboss.seam.preDestroy.MySessionBean
event is never raised. And Session.instance().invalidate(); had no effect.
So I did some debugging and saw that the org.jboss.seam.webservice.SOAPRequestHandler never calls ServletLifecycle.endRequest(request); in contrast to the org.jboss.seam.servlet.ContextualHttpServletRequest.run() method. So I implemented a subclass of Seam's SOAPRequestHandler calling the ServletLifecycle.endRequest(request); method in the SOAPRequestHandler.close(...) method.
Should this be filed as a bug?
Now Session.instance().invalidate(); has an effect and the HttpSession becomes invalid, but my session bean still isn't destroyed. After more debugging I found that org.jboss.seam.servlet.SeamListener.sessionDestroyed(HttpSessionEvent) called ServletLifecycle.endSession(...). Because I found no way to register a HttpSessionListener for JBoss' webservice endpoint servlet, I called this method in the SOAPRequestHandler.close(...) method if the session was invalid, but this caused a NPE:
java.lang.NullPointerException at org.jboss.seam.contexts.Lifecycle.endSession(Lifecycle.java:282) at org.jboss.seam.contexts.ServletLifecycle.endSession(ServletLifecycle.java:160) at my.SOAPRequestHandler.close(SOAPRequestHandler.java:56)
Lifecycle.java:282 is:
Set<String> conversationIds = ConversationEntries.instance().getConversationIds();
so the instance() method seems to return null.
The complete code of my custom SOAPRequestHandler.close() implementation:
@Override public void close(MessageContext messageContext) { HttpServletRequest request = (HttpServletRequest) messageContext.get(MessageContext.SERVLET_REQUEST); ServletLifecycle.endRequest(request); if(!request.isRequestedSessionIdValid()) { ServletLifecycle.endSession(request.getSession()); } super.close(messageContext); }
At this point I don't know how to proceed. Hope someone can help me!
My Environment:
- JBoss 5.1.0.GA
- JBoss Seam 2.2.0.GA