View Full Version : HessianServlet with Session Scoped dependencies

06-30-2010, 02:52 PM
Good day,

I am trying to communicate to my CDI bootstrapped JavaEE application via Hessian. The problem I have is that each client invocation of the Hessian servlet seems to be done in a new CDI session.

My Hessian servlet:

public class WebServiceRemoteInvocationHandler extends HessianServlet implements
RemoteInvocationHandler {

private static final long serialVersionUID = 1L;

private ServerState serverState;

public RemoteInvocationResult invoke(RemoteInvocationCommand cmd) {
System.out.println(serverState.toString()); //should be same on every call from the same client


my ServerState implementation:

public class SessionMapServerState implements ServerState, Serializable {

private static final long serialVersionUID = 1L;


and my client (which runs as a normal Java SE process using a SE bootstrapped CDI container like Weld or ResinContainer):

public class AppStart {

public RemoteInvocationHandler getRemoteInvocationHandler()
throws Exception {
HessianProxyFactory factory = new HessianProxyFactory();
RemoteInvocationHandler remote = (RemoteInvocationHandler) factory
return remote;

How can I enable the use of sessions from my SE application? I assume there must be some way to create and destroy a client session similar to what HttpClient does, but alas my knowledge of Hessian is a bit limited.

07-01-2010, 12:26 AM
I've added a bug report for this.

Hessian is designed to be stateless, so technically sessions don't make sense. But since it's a feature that's been asked for before, I'll add a bug report for it.

07-01-2010, 07:46 AM
Thanks Scott, I managed to get it to work by simply enabling cookie management via the java.net.CookieHandler.

07-05-2010, 11:48 AM
Alas, it seems as if this issue is still haunting me!

So using the above approach (Hessian servlet together with cookie management on the client) I have managed to get Resin to correctly use a session scoped Map that "survives" multiple client requests.

However, I was doing some testing and noticed that objects that I stored in my SessionScoped server side Map never gets garbage collected, even though the session properly times out. Increasing the log level of my server, I notice that whenever the hessian servlet session times out, I get the following error on my console:

[13:32:54.993] {resin-32} SessionImpl[aaaKevsSpi-4I5cyExIMs,/alchemy-no-test-app-web] timeout
[13:32:54.993] {resin-32} SessionImpl[aaaKevsSpi-4I5cyExIMs,/alchemy-no-test-app-web] remove
[13:32:54.993] {resin-32} javax.enterprise.context.ContextNotActiveException : com.caucho.server.webbeans.SessionScope cannot be used because it's not currently active
at com.caucho.config.scope.AbstractScopeContext.get(A bstractScopeContext.java:91)
at com.caucho.config.inject.InjectManager$NormalInsta nceReferenceFactory.create(InjectManager.java:4251 )
at com.caucho.config.inject.InjectManager$ReferenceFa ctory.create(InjectManager.java:4010)
at alchemy.remote.server.impl.SessionMapServerState__ ResinScopeProxy.destroy(Unknown Source)
at alchemy.no.session.context.rwt.AlchemySessionListe ner.sessionDestroyed(AlchemySessionListener.java:4 0)
at com.caucho.server.session.SessionImpl.notifyDestro y(SessionImpl.java:1018)
at com.caucho.server.session.SessionImpl.removeEvent( SessionImpl.java:995)
at com.caucho.util.LruCache.remove(LruCache.java:613)
at com.caucho.server.session.SessionManager.removeSes sion(SessionManager.java:1581)
at com.caucho.server.session.SessionImpl.invalidate(S essionImpl.java:1090)
at com.caucho.server.session.SessionImpl.invalidateTi meout(SessionImpl.java:1045)
at com.caucho.server.session.SessionImpl.timeout(Sess ionImpl.java:951)
at com.caucho.server.session.SessionManager.handleAla rm(SessionManager.java:1665)
at com.caucho.util.Alarm.handleAlarm(Alarm.java:453)
at com.caucho.util.Alarm.run(Alarm.java:425)
at com.caucho.util.ThreadPool$PoolThread.runTasks(Thr eadPool.java:901)
at com.caucho.util.ThreadPool$PoolThread.run(ThreadPo ol.java:866)

I fear this exception might be preventing Candi from properly cleaning up the session state, and hence my server side objects never gets released.

07-05-2010, 12:00 PM
Ah, upon further inspection, I must add that I have a servlet listener registered on my application:

public class AlchemySessionListener implements HttpSessionListener,
ServletRequestListener {

private ServerState serverState;

private Logger log;

public void sessionCreated(HttpSessionEvent ev) {

public void sessionDestroyed(HttpSessionEvent ev) {


The problem seems to be that the CDI session is closed before the servlet listener's sessionDestroyed(..) method is invoked.

According to the CDI spec (section 6.7.2):

The session context is shared between all servlet requests that occur in the same HTTP session. The session context is destroyed
when the HTTPSession times out, after all HttpSessionListeners have been called

07-06-2010, 05:38 AM
Oh dear, more trouble. It seems as if the approach using java.net's cookies only goes that far - HessianServlet seems to take liberties with the servlet context, which sometimes results in the wrong session being returned when I have multiple clients connected at the same time.

Is it a fool's errand to use session scope with Hessian at this stage, or am I simply doing something wrong? If my client uses the JSESSIONID cookie as per the servlet spec, should HessianServlet not bootstrap the CDI session correctly for each client, or is there some dark magic happening inside HessianServlet that causes Resin to inject the wrong session's bean into the active session?

07-06-2010, 07:58 PM
Well, the CDI listener issue looks like a Resin bug (the session close is currently implemented by a listener as well.)

For the other issues, Hessian doesn't directly support sessions/cookies at the moment, so it's possible the tweak you're using is running into some other issues.

07-07-2010, 07:32 AM
Thanks Scott,

I found the reason for the problem of the wrong scope being loaded - it was my test that was broken, not HessianServlet or anything in Resin. When using a CookieHandler, the HessianServlet correctly loads the correct the scope as per the servlet spec.