Announcement Announcement Module
Collapse
No announcement yet.
Websphere 8/8.5 + Webflow + Mojarra JSF 2.x isMyfacesPresent bug Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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)
    Last edited by matt.deboer; Nov 12th, 2012, 04:07 PM.

  • #2
    The following modification to JsfRuntimeInformation seems to work correctly on websphere 7, 8 & 8.5 (and I imagine should work correctly on other platforms as well, though I've only tested on these). It test the implementation of the underlying faces ApplicationFactory to determine whether MyFaces is the implementer.


    Code:
    ...
    private static final boolean myFacesPresent;
    
    	static {
    		if (ReflectionUtils.findMethod(FacesContext.class, "isPostback") != null) {
    			jsfVersion = JSF_20;
    		} else if (ReflectionUtils.findMethod(FacesContext.class, "getELContext") != null) {
    			jsfVersion = JSF_12;
    		} else {
    			jsfVersion = JSF_11;
    		}
    		
    		/*
    		 * MyFaces is "present" if the ApplicationFactory implementation is provided by MyFaces 
    		 */
    		ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
    		boolean isMyFacesPresent = false;
    		while (appFactory != null) {
    			if (appFactory.getClass().getCanonicalName().startsWith("org.apache.myfaces")) {
    				isMyFacesPresent = true;
    				break;
    			} else {
    				/*
    				 * A third-party library may have wrapped the factory; once we get down to the base 
    				 * implementation, null should be returned from getWrapped() 
    				 */
    				appFactory = appFactory.getWrapped();
    			}
    		}
    		myFacesPresent =  isMyFacesPresent;
    	}
    ...

    Comment


    • #3
      Very Thanks from Mexico City , i have two project in my current , i developer they with Spring webflow 2.3.2 springframework 3.2.3 after i change a next version for test this solution comment in this post


      <java-version>1.5</java-version>
      <springframework-version>3.2.3.RELEASE</springframework-version>
      <springwebflow-version>2.3.1.RELEASE</springwebflow-version>
      <springsecurity-version>3.1.4.RELEASE</springsecurity-version>
      <org.slf4j-version>1.6.1</org.slf4j-version>

      my deploys in tomcat 6 with jdk 1.6 y jdk 1.7 and tomcat 7 with jdk 1.6 and jdk 1.7 worked without problem, my two project website working very good,

      But i have problems when , i try for cuestions of my work, i have deploy one of two applications in websphere 8.0 , because in my current client , yours applications server deploy for internet is used WAS 8.0 .

      First problem i dont know how configure the server for deploy of my project site web, for the conflict libraries for implement in first loading my libraries war of mojarra implementations:
      jsf-impl-2.1.20.jar
      jsf-api-2.1.20.jar
      commons-fileupload-1.3.jar
      primefaces-3.5.7-UR.jar


      in my firsts deploys i have problem the conflict between implementations JSF jar owner websphere 8.0, this problem solution, fix create a Associating shared libraries with applications or modules in mode isolated, and asocciated with my module web war

      y mark from my application from console websphere in my module loading class firt local (parent last)

      after i have other problem , "Could not find backup for factory javax.faces.lifecycle.LifecycleFactory"
      i have two day searching one solution , WebFlow beginning to think in websphere 8.0 not working after two days to find a solution and not finding

      luckily I care your post and I thought that I could be the solution to my problem, and so the modification was made ​​in the class JsfRuntimeInformation.java, recompile this class and replace in spring-faces-2.3.1.RELEASE.jar this class and returned to deploy my project war and it worked, thank you very much you saved me

      It's important to add in web.xml the listener

      <listener>
      <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
      </listener>

      before of create war and deploy in console websphere 8


      I take how base the project of git SpringPrimeFacesShowcase-master.zip for my project site and test this solution and worked very!!

      I hope this info can help someone in my same situation

      Comment


      • #4
        sorry for my poor english

        Comment

        Working...
        X