JSF Session Failover Issue

I'm having some problems with a session-scoped pagecode object in a failover scenario and would appreciate any suggestions. Here's the situation:

I have a pagecode class that retrieves a user bean from the session in an action listener method. In a standalone server environment it works just fine,

and even in a clustered environment it works okay -- until the server on which the user is operating is taken down. The session data is successfully failed

over to the other server and the user's next request is routed to said server. However, if the aforementioned action listener method is then invoked, I now

get IllegalStateExceptions when trying to get the user bean out of the session. Here's the code:

publicclass MyPagecodeextends PageCodeBaseimplements Serializable{

publicvoid firePrepareForPreview(ActionEvent event){

UserBean user = UserBean.getFromSessionScope(this.getSessionScope());

//do something with the user bean

}

}

publicclass PageCodeBase{

public PageCodeBase(){

getSessionScope();

}

protectedtransient Map sessionScope =null;

public Map getSessionScope(){

if(sessionScope ==null){

sessionScope =

(Map)FacesContext.getCurrentInstance()

.getApplication()

.createValueBinding("#{sessionScope}")

.getValue(facesContext);//this line is reached either

//a) in a standalone server mode when the pagecode object is created (this works),

//b) via the action listener method above after the object is failed over, causing the sessionScope variable

//to be set to null (not serializable)

}

return sessionScope;

}

}

Stack Trace:

Caused by: javax.faces.el.EvaluationException: java.lang.IllegalStateException

at com.sun.faces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:131)

at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:73)

... 32 more

Caused by: java.lang.IllegalStateException

at com.sun.faces.context.FacesContextImpl.assertNotReleased(FacesContextImpl.java(Compiled Code))

at com.sun.faces.context.FacesContextImpl.getApplication(FacesContextImpl.java:122)

at pagecode.PageCodeBase.getSessionScope(PageCodeBase.java:254)

at pagecode.enews.admin.EditMessage.previewMessage(EditMessage.java:56)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))

at java.lang.reflect.Method.invoke(Method.java(Compiled Code))

at com.sun.faces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:127)

... 33 more

It's apparent that calling createValueBinding is okay when the pagecode object is constructed by the faces runtime (happens when all servers are

go), but not from within my action listener method (happens when failover occurs). Perhaps I cannot call createValueBinding during this phase, but I've

tried calling getExternalContext() as well to no avail. I don't see how I"m supposed to get the userbean out of the session in this scenario.

If I shouldn't be accessing the session data from an actionlistener or an action, what is the correct way to do it? Any help you can offer would be appreciated. Thx

[4617 byte] By [Byron_Baileya] at [2007-11-26 18:22:40]
# 1

I figured it out. The problem has nothing to do with the fact that we're running in a cluster -- that just revealed the problem. This is the classic problem I have seen elsewhere -- although I call "FacesContext.getCurrentInstance()" in one spot, I use the facesContext object that is an instance variable in my PageCodeBase class. Furthermore, that facesContext was one from a previous request that has been released since my pagecode bean is session scoped.

Be aware, all that use the PageCodeBase class (it is generated by some of the tooling out there. In my case, it was RAD). I sinfully assumed that the generated code was solid and could be trusted, but apparently not. Although it should work just find and dandy when the scope of the pagecode managed bean is "request", as soon as you switch it to "session" things get screwed up since it stores the facescontext, request parameters, etc. as instance variables.

Thus, a disclaimer... if you use a session-based scope for a pagecode managed bean that extends "PageCodeBase" class, you will probably need to rewrite some of the generated methods (don't store the maps and faces context as instance variables). For example, here's what I changed my getSessionScope() method to:

public FacesContext getFacesContext() {

return FacesContext.getCurrentInstance();

}

public Map getSessionScope() {

FacesContext context = this.getFacesContext();

return (Map) context

.getApplication()

.createValueBinding("#{sessionScope}")

.getValue(context);

}

Byron_Baileya at 2007-7-9 5:56:34 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

To be honest, the PageCode classes did raise some warning flags. I wasn't sure enough to comment though. In any case, good call on the generated code. I've found that more often than not, especially in IBM IDEs, the generated code for JSF is not worthwhile. I personally have deleted ALL references to pagecode and suppress the IDE from generating it. The pagecode just messes things up and clutters your projects. Plus, it's not even necessary.

Also, I would go download the JSF jars from sun (or apache, for whatever version of the framework you are using). Then force your JSF projects to use the downloaded versions of the JSF jars. i.e. Remove all references to the IBM IDE generated JSF jars. The IBM JSF jars have caused me grief for no good reason.

CowKing

IamCowKinga at 2007-7-9 5:56:35 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
Would it not simply have been better to have your UserBean injected into the page code using the managed bean facility and not have to go and look it up yourself?-Chris
Chris_Grahama at 2007-7-9 5:56:35 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...