0

I have a web app running on in a CICS environment on Liberty servers. For workload management, the application session is set up to shift between 3 different servers, which occurs randomly during a given session. Implementing this, I am currently receiving the following error:

Error 500: javax.servlet.ServletException: /{page_name}.xhtml - No saved view 
state could be found for the view identifier: /{page_name}.xhtml

The error happens at random, but it appears that it only occurs when the application session has hopped to a different server. I verified this by shutting down two servers, and saw that a session would run without any problems after that. My application has security and requires login credentials when a session starts, and I believe this is somehow affecting the rendering of pages when it jumps servers, as if the credentials are not jumping with the session. I did some research and attempted to switch the state_saving method from server to client by adding the following context param to the applications web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>        
    <param-value>client</param-value>
</context-param>

Unfortunately, the issue still persists. Any suggestions would be much appreciated. If any more information or a larger stack trace is needed, please comment below!

EDIT: Stacked Trace:

[2/12/19 15:25:53:672 CST] 00000056 com.ibm.ws.webcontainer.webapp                               
E SRVE0315E: An exception occurred: java.lang.Throwable: 
javax.servlet.ServletException: /pltdisable.xhtml - No saved view state 
could be found for the view identifier: /pltdisable.xhtml
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5006)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.handleRequest(DynamicVirtualHost.java:314)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:995)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:279)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1009)
at com.ibm.cics.wlp.impl.CICSHttpRunnable.run(CICSHttpRunnable.java:244)
at com.ibm.cics.wlp.impl.CICSTaskWrapper.runWork(CICSTaskWrapper.java:762)
at com.ibm.cics.wlp.impl.CICSTaskWrapper.run(CICSTaskWrapper.java:415)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at com.ibm.cics.wlp.threading.CICSThread.run(CICSThread.java:245)
at com.ibm.cics.wlp.threading.CICSPooledThreadFactory.joinAsThreadInternal(CICSPooledThreadFactory.java:409)
at com.ibm.cics.wlp.threading.CICSPooledThreadFactory.joinAsThread(CICSPooledThreadFactory.java:335)
at com.ibm.cics.server.internal.ThreadJoiner.main(ThreadJoiner.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at com.ibm.cics.server.Wrapper.call_main(Wrapper.java:893)
at com.ibm.cics.server.Wrapper.callOSGiClass(Wrapper.java:2816)
at com.ibm.cics.server.Wrapper.invokeJvmServerOSGiClass(Wrapper.java:2683)
at com.ibm.cics.server.Wrapper.jvmServerOSGiEntry(Wrapper.java:2612)
at com.ibm.cics.osgi.impl.Controller.runService(Controller.java:1413)
at com.ibm.cics.osgi.impl.Controller.acceptRequest(Controller.java:322)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at com.ibm.cics.router.Router.route(Router.java:1317)
Caused by: javax.servlet.ServletException: /pltdisable.xhtml - No saved view 
state could be found for the view identifier: /pltdisable.xhtml
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:743)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:440)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1155)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:4962)
... 28 more
John W
  • 9
  • 4
  • Can you post the stack of the ViewExpiredException? – wtlucy Feb 13 '19 at 13:31
  • The stack doesn't make it clear, but this might be caused by misconfigured MyFaces encryption. As a test, try disabling encryption, as described here: https://wiki.apache.org/myfaces/Secure_Your_Application (set org.apache.myfaces.USE_ENCRYPTION=false) – wtlucy Feb 13 '19 at 16:48
  • That could work as a temporary fix, but this program will run in a production environment in the future.I will test it for now. – John W Feb 13 '19 at 19:20
  • Right, only disable encryption as a test - the linked wiki includes instructions for proper configuration (mainly adding secrets) – wtlucy Feb 13 '19 at 19:43
  • Hey thanks for that. I was a little busy today. I'll take a stab at it tomorrow, and will comment about how it went. – John W Feb 13 '19 at 21:47
  • To my understanding configuring the encryption manually would be no different than a default configuration, as it states even if the secret is not specified it will be generated automatically. I did however, read the part about view saved state error after. I suspect possibility that thay may be the cause, but I've also deleted and rebundled the application with no success. – John W Feb 14 '19 at 15:10
  • The documentation isn't very clear - the point of explicitly adding the secret key to the app is so that it will be the same for each server in the cluster. Otherwise, by default each server will generate its own independent random key. – wtlucy Feb 15 '19 at 13:34
  • Hey. That was a great spot. That actually solved my problem, and allowed me to encrypt. Now I don't have to leave the application disabled. – John W Feb 15 '19 at 15:20
  • I have one last comment for you @wtlucy . I'm not in full understanding of the encryption process at this time. I simply copied and pasted over those configuration parameters. Should I rearrange any of those keys to ensure security, and if so. How would I do so? Also, if you explain this as a solution, I will mark it as the answer. – John W Feb 15 '19 at 15:22

2 Answers2

2

Given your scenario, it's likely that the No saved view state error occurs when a request is routed to a different server than the one on which its session began, and that new server cannot process the view state it's passed.

This happens because MyFaces has view state encryption enabled by default - and by default, the secret keys for that encryption are generated randomly at startup. So given a completely default configuration, different servers in a cluster won't be able to share encrypted view states, because each server will have been initialized with a different random secret key. In order to share encrypted view states between servers, those servers need to have been configured to use the same secret keys. Those can be set via these web config parameters:

<!-- Defines the secret (Base64 encoded) used to initialize the secret key
     for encryption algorithm. The size of it depends on the algorithm used for encryption -->
<context-param>
    <param-name>org.apache.myfaces.SECRET</param-name>
    <param-value>your_secret_key</param-value>
</context-param>

<!-- Define the initialization code (Bas64 encoded) that are used to initialize the secret key used
     on the Message Authentication Code algorithm. The size of it depends on the algorithm used for mac calculation -->
<context-param>
    <param-name>org.apache.myfaces.MAC_SECRET</param-name>
    <param-value>your_mac_secret_key</param-value>
</context-param>

The MyFaces wiki details security configuration. The default security parameter settings - in addition to your secret keys - are sufficient for a secure deployment.

wtlucy
  • 704
  • 3
  • 10
0

This post discusses some other options for the same problem, if you can't get the client side state saving working. No saved view state could be found for the view identifier

Also if you are defaulting to using LTPA for security, you should also be sharing the ltpa.keys file between your Liberty servers.

  • I am using saf authorization in combination with EJB roles for security. I will check to make sure the ltpa.key is shared. – John W Feb 13 '19 at 14:51
  • I verirfied that the ltpa.keys file is shared by all three servers. – John W Feb 13 '19 at 15:23