0

I have a very strange error: No saved view state could be found for the view identifier: /mypage.xhtml
The problem is that it appears randomly, to just ~10% of the users/executions.

Application server: Apache Tomee 1.5.2 stable / 1.6.0-2013.09.20 dev (It happens on both). I use the MyFaces distribution that comes with each of them, so 2.1.10 / 2.1.12, so nothing new added.

Part of web.xml:

      <context-param>
        <param-name>org.apache.myfaces.USE_ENCRYPTION</param-name>
        <param-value>false</param-value>
      </context-param>
      <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
      </context-param>

So, no state view exception shouldn't happen, because state is on client. It was set on server before, but I thought maybe client will fix it, but nothing. There was actually no difference in the occurrence of that error.

Execution flow:
1. Client opens xhtml page (JSF).
2. Client clicks on an command button to do various things, button connected to a public void method of a JSF @ViewScoped ManagedBean.
3. Yes, the method is void because I don't need to return a String to redirect to another page. I need to redirect to /page/id (example: /market/24, /profile/43), therefore methods that return a String as navigation destinations are useless, because I use: FacesContext.getCurrentInstance().getExternalContext().redirect(path);
4. In ~90% of the cases, everything works perfectly and users are redirected to each specific page. In the rest of ~10 (randomly), they get No saved view state could be found for the view identifier: /pagename.xhtml

I would really appreciate some help here, because I have no idea how to get it fixed.
Thanks a lot in advance.

PS. I use PrimeFaces and I also have a couple of my own filters in web.xml, but that shouldn't be a problem, I hope so.

Stack trace for one of the pages:

25-Sep-2013 07:39:26.380 SEVERE [http-bio-80-exec-15] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [Faces Servlet] in context with path [] threw exception [/dashboard/edit-profile.xhtmlNo saved view state could be found for the view identifier: /dashboard/edit-profile.xhtml] with root cause
 javax.faces.application.ViewExpiredException: /dashboard/edit-profile.xhtmlNo saved view state could be found for the view identifier: /dashboard/edit-profile.xhtml
        at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:132)
        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:77)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:199)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at com.pingushare.boundary.filter.ActivateAccountFilter.doFilter(ActivateAccountFilter.java:37)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at com.pingushare.boundary.filter.SecurityFilter.doFilter(SecurityFilter.java:36)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at com.pingushare.boundary.filter.ForceFreshPageAndWWWFilter.doFilter(ForceFreshPageAndWWWFilter.java:49)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)
MWiesner
  • 8,868
  • 11
  • 36
  • 70
zmirc
  • 825
  • 2
  • 11
  • 27

2 Answers2

0

This issue is well understood and it happens because if the server is restarted or the application is redeployed, a new encryption key is generated by default. The solution is generate your own key and set it up in your web.xml file. In that way, MyFaces will use the same key at all times. See http://wiki.apache.org/myfaces/Secure_Your_Application

The description claims that encryption is disabled, and I have checked the code and it is ok, it works as expected (the encryption is effectively disabled). If the encryption is not the problem, my opinion is there is an error in your application logic. Don't call redirect in that way, use the standard form using mypage.xhtml?faces-redirect=true . The problem could be caused by a session expiration (note only view scope beans goes to the client in 2.0/2.1, but session scope beans are expired).

lu4242
  • 2,318
  • 1
  • 15
  • 15
  • Hi! It's not related to restart, as you've also mentioned. I as have explained in my post, mypage.xhtml?faces-redirect=true isn't useful for prettyfaces URLs. Example: how do you redirect to: /mypage/ID1/ID2 with that way of doing it? Secondly, session timeout is set to 30 days in web.xml (302400). The error happens at random times for random users, but all users didn't use the system yet for 30 days, so it's a little bit strange. Any other ideas? – zmirc Sep 25 '13 at 08:37
  • How can you get a "No saved view state could be found for the view identifier:" on a GET? I'm pretty sure it is related to the way you are calling redirect. – lu4242 Sep 25 '13 at 09:06
  • It doesn't happen on a GET. I have mentioned the following: step 2: user clicks on a command btn, step 3: btn is connected to a method, step 4: something goes wrong, so method is not executed (less than 10~ of cases...very random anyway). The method it's not even reached because of this No state error. – zmirc Sep 25 '13 at 09:09
  • But the redirect is a GET, right? So that code effectively breaks the JSF lifecycle. It doesn't work because that doesn't supposed to be working. – lu4242 Sep 25 '13 at 09:18
  • Yes, the redirect is a GET, but that's not the case, because the command button's method is not executed at all, so JSF didn't reach to that line of code (redirect). – zmirc Sep 25 '13 at 09:27
  • ... I see. I'm starting to think the redirect stuff should not be the problem, and the problem is before on the command button. One option is in some point, the view state gets corrupted and the algorithm cannot restore the state properly. Try enabling encryption and set a secret and a mac secret as described in the page. If everything works, it could be that disable encryption introduce some characters in the state. In that case just ping on the issue open and I'll check that again. – lu4242 Sep 25 '13 at 11:13
  • I will try that and come back with feedback. I can't reproduce the error, so I have to wait a little in production, to see if it will happen again. Thanks A LOT for helping. – zmirc Sep 25 '13 at 11:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38039/discussion-between-zmirc-and-lu4242) – zmirc Sep 25 '13 at 16:07
  • interesting discussion. can you update your post with PrimeFaces version and maybe 1 or 2 xhtml (commandButton/Link) code snippet? also, are you using (or have you considered adding) OmniFaces (enableRestorableView) component which was specifically designed/implemented-for viewExpiredException (for client and server state saving, I think). I added it to my app, and I use server state saving, TomEE+ (latest version, most of the time), session-timeout 30 minutes. i don't experience this issue. also, how many users are using app when this occur? can you obtain browser (cache) settings when occur? – Howard Sep 27 '13 at 12:50
  • oh, and i'm not using prettyfaces and i only do HttpResponse.redirect from my http/login filter. I do faces redirect string only when POST from login.xhtml to index.xhtml. – Howard Sep 27 '13 at 12:52
0

After long discussions on MyFaces and Tomee forums/mailing lists, this is how I managed to eliminate this problem: I switched the JSF implementation in this project to Majorra 2.1.26. The error didn't appear anymore until now.

As this bug didn't make any sense (after checking source of both my project and MyFaces) and couldn't be reproduced, we couldn't actually find a fix for it, but at least it doesn't happen in Majorra, so this could be helpful if someone else gets this error.

Mention: this is not the basic "no saved view state could be found" that many JSF developers get. That's something else hiding somewhere.

zmirc
  • 825
  • 2
  • 11
  • 27