I am in the process of upgrading the JSF implementation in an existing project, that uses MyFaces 1.1, to version 2.1. I mainly follow the instructions given in Migrating from JSF 1.2 to JSF 2.0.
Since I plan to upgrade just JSF for now and postpone switching from JSP to Facelets and updating component libraries to a later time, I have for now just done the following steps:
- Update the MyFaces libraries by updating the version of my
myfaces-apiandmyfaces-implartifacts from<version>1.1.5</version>to<version>2.1.18</version>in my mavenpom.xml Update the
faces-config.xmlto comply with JSF 2.1 from<faces-config>to<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1">Update the
web.xmlto<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">
Now, when I try to open the application in a browser I get the normal starting page displayed correctly, but when I click any link, I get the following error:
javax.faces.application.ViewExpiredException: /pages/View.jsf - No saved view state could be found for the view identifier: /pages/View.jsf
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:171)
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.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
...
I didn't get this error when using the application with MyFaces 1.1, it has to be connected to the few changes I made right?
I tried the following to alliviate the problem:
- verify that the
javax.faces.STATE_SAVING_METHODparameter is set toserverin myweb.xml(according to ViewExpiredException: No saved view state could be found: on submitting a form in JSF) add the
org.apache.myfaces.SERIALIZE_STATE_IN_SESSIONparameter to myweb.xml(after reading here that MyFaces 2.1 defaults this parameter totruein contrast to later Mojarra 2.1 and later MyFaces versions):<context-param> <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name> <param-value>false</param-value> </context-param>set the
javax.faces.DEFAULT_SUFFIXparameter to.jspsince I thought the FacesServlet might look for*.xhtmltemplates instead now for JSF 2.x:<context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.jsp</param-value> </context-param>set the
org.apache.myfaces.USE_ENCRYPTIONparameter tofalsesince it seems to default totruein MyFaces 2.1 (according to Secure Your Application and the first answer in Random JSF error: no saved view state could be found implies that re-issuing encryption keys could cause the problem):<context-param> <param-name>org.apache.myfaces.USE_ENCRYPTION</param-name> <param-value>false</param-value> </context-param>make sure that the FacesServlet is defined in the
web.xmland that URLs ending with.jsfare mapped to it:<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping>
None of the steps above solved the error, so I am a little lost as to where it stems from - especially since I didn't touch the templates themselves, yet, just the configuration files.
Edit: I just discovered ViewExpiredException on every navigation after migrating from JSF 1.2 to JSF 2.0 Perhaps switching the JSF implementation would work, but the second answer in that post states that this particular bug in MyFaces is fixed in versions 2.0.7 and 2.1.1, so I expect it would be fixed in 2.1.18, too (which I try to upgrade to). The other reason why I hesitate on switching to Mojarra is that our project uses the GPL 3.0 license which - according to https://www.gnu.org/licenses/license-list.en.html - is not legally compatible to the CDDL license used by Mojarra, if I am not mistaken.
Edit 2: currently, the webapp also uses Ajax4JSF, and from Migrating JSF 1.1 with Ajax4jsf 1.x to JSF 2 I get that I need to replace the a4j tags with the f:ajax tag in my JSP files for JSF2.
On the other hand, JSF 1.2- >2.0 :viewId parameter for save view state is null reads like the f:ajax tag from JSF2 can't be used with JSP, or does this only apply to very old versions of JSP, like JSP 1.x (which is what I get from the "Old JSP is not fully supported by JSF 2" in why <f:ajax> tags doesnt work in JSP with JSF2.0)?
Is it right that since in my web.xml I have <web-app version=2.5 and because I deploy the webapp on a Tomcat 7 servlet container that I indeed am using JSP 2.2 (according to https://wiki.apache.org/tomcat/TomcatVersions), which should allow the use of the f:ajax tag from JSF2?
Could this cause the error I am experiencing?
Edit 3: I added the whole stack trace to the post and just realised that it contains indeed a reference to the ajax4jsf library, in form of the line
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) (see whole stack trace above).
Could the incompatibility of JSF2 with the ajax4jsf library indeed cause the error? It is invoked by the servlet, though, and not by our application, so I do not understand how to fix this problem.
Any help with this would be greatly appreciated!