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-api
andmyfaces-impl
artifacts from<version>1.1.5</version>
to<version>2.1.18</version>
in my mavenpom.xml
Update the
faces-config.xml
to 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.xml
to<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_METHOD
parameter is set toserver
in 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_SESSION
parameter to myweb.xml
(after reading here that MyFaces 2.1 defaults this parameter totrue
in 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_SUFFIX
parameter to.jsp
since I thought the FacesServlet might look for*.xhtml
templates 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_ENCRYPTION
parameter tofalse
since it seems to default totrue
in 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.xml
and that URLs ending with.jsf
are 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!