Websphere 8/8.5 + Webflow + Mojarra JSF 2.x isMyfacesPresent bug
I just finished a battle to use webflow (2.3.1) with Mojarra JSF 2.1.x in Websphere 8 and Websphere 8.5 (testing against both), and thought I would pass along the workaround for anyone else in the same scenario.
To begin, we had simple Mojarra JSF 2 + webflow app which was working great in Websphere 7, so long as we configured the class-loader to PARENT_LAST. By simple, I mean the app configuration was originally based on the Spring faces booking app and contains one flow with 2 view states, each page only has buttons used to navigate from page to page. Upon attempting to deploy the same app to Websphere 8 and 8.5, the behavior is that the first page would return a redirect in a loop. Using the 2.1.14 version of Mojarra got me past the invalid redirect, but would cause the initial flow to be restarted on every event. A little digging showed that FlowViewStateManager.restoreTreeStructure(...) was returning null.
I had javax.faces.PARTIAL_STATE_SAVING set to 'true' in the web.xml, but some further debugging showed that JsfRuntimeInformation.isPartialStateSavingSupporte d() was returning false. The root culprit turned out to be this line in JsfRuntimeInformation:
Code:
private static final boolean myFacesPresent = ClassUtils.isPresent("org.apache.myfaces.webapp.MyFacesServlet",
JsfUtils.class.getClassLoader());
In Websphere 8 and 8.5, it seems that myfaces is always on the classpath, no matter what you do (thanks, Websphere). Since JsfRuntimeInformation will return 'false' from isPartialStateSavingSupported() if myfaces is present, then a conflict is created where the JSF components think partial state saving is supported, while webflow thinks it is not; thus, wacky hijinks ensue.
My short-term workaround was to provide my own copy of JsfRuntimeInformation which avoids the MFacesServlet class lookup and always returns 'false' for the isMyfacesPresent(); I'll post back if I come up with a more robust solution that will work in Websphere 8/8.5 (hopefully, the webflow committers will find something better). The summary is that it seems that just checking for particular MyFaces classes on the classpath is not going to work in Websphere 8 +, since they will always be there.
(Note that the results are the same, whether you select "DEFAULT", "SunRI1.2", or "MyFaces2.0"; myfaces is always on the classpath)