Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with numberOfViewsInSession and multiple tabs

I have a big problem with my application and the memory. The application (java with jsf/richfaces/facelet) is used by some 7000 users simultaneously.

By default, the variable com.sun.faces.numberOfViewsInSession is set to 15 in the web.xml. This variable create a tree of views and jsf retrieve a specific view during 15 click backwards.

For example, I have 3 screens for an application and I use firefox. I go in third screen in a first tab. In a second tab, I have the first screen and I click on the next button, jsf retrieve the first screen and go to the second.

This mechanism is great but it consumes a lot of memory (25Mo by session for me) and when you multipy this number by 7000, I need 175 Go of memory, it's impossible.

So I tried to set com.sun.faces.numberOfViewsInSession equal to 1 (3Mo by session).

But with my example, when I click in the second tab on the next button I get the next error:

javax.servlet.ServletException: viewId:/private/pages/data/dataView.faces - View /private/pages/data/dataView.faces could not be restored.
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at fr.generali.mezzo.front.commun.performance.filters.PerformanceFilter.doFilter(PerformanceFilter.java:72)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:525)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:420)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:595)

This error is logical because my numberOfViewsInSession is 1.

So, my question is:

Given that I know data which are in the view (for the second tab), how can I do to catch the exception and create a new view for my user ?

Thanks for your help.

like image 215
Kiva Avatar asked Dec 28 '10 16:12

Kiva


1 Answers

Restoring the view manually by exploiting the specific knowledge you have about your application is maybe not a task for the faint-hearted.

If you would like to follow that path, I think you should not attempt to catch the exception, but to take advantage of the StateManager API in JSF. This allows you to customize the way how the JSF framework manages its view state.

Do note that this is an advanced topic. Or in Ed Burns' (JSF spec lead) words:

View state management is a complex business, and few application developers will have to worry about customizing it.

That said, if you're not already using JSF 2.0, then I highly recommend upgrading to this. A big new feature in JSF 2.0 is Partial State Saving. This dramatically reduces the amount of memory needed to store state.

Yet another option, which I guess you might have already considered seeing you have knowledge of parameters like com.sun.faces.numberOfViewsInSession is using state on client. This stores the view state in hidden fields, and basically given you an unlimited memory since the client is used as distributed memory. Of course this comes at the expensive of increased network overhead. In case of AJAX this overhead might be so large that it's impossible to consider.

like image 165
Arjan Tijms Avatar answered Oct 31 '22 19:10

Arjan Tijms