MyFaces Trinidad
  1. MyFaces Trinidad
  2. TRINIDAD-955

ClassCastException in StateManagerImpl on PPR

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.2.6-core
    • Fix Version/s: 1.2.7-core
    • Component/s: Archetype
    • Labels:
      None
    • Environment:
      Facelets 1.1.14, JSF 1.2_07 RI

      Description

      On attempt to PPR, the following exception is thrown:

      Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.String
      at org.apache.myfaces.trinidadinternal.util.SubKeyMap._getBaseKey(SubKeyMap.java:116)
      at org.apache.myfaces.trinidadinternal.util.SubKeyMap.get(SubKeyMap.java:75)
      at org.apache.myfaces.trinidadinternal.application.StateManagerImpl.restoreView(StateManagerImpl.java:526)
      at com.sun.faces.application.ViewHandlerImpl.restoreView(ViewHandlerImpl.java:318)
      at com.sun.facelets.FaceletViewHandler.restoreView(FaceletViewHandler.java:316)
      at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:204)
      at org.apache.myfaces.trinidadinternal.application.ViewHandlerImpl.restoreView(ViewHandlerImpl.java:260)
      at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:176)
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
      at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
      at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
      ... 19 more

      Instead of returning token string, an array of objects is returned by ResponseStateManager.getTreeStructureToRestore().

      This affects trinidad-1.2.6 (maybe the issue is caused by changes in revision #614404 ?). trinidad-1.2.5 is ok

        Activity

        Show
        Matthias Weßendorf added a comment - In rev 600997 there was no change http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java?view=log
        Hide
        Alexey Stukalov added a comment -

        sorry, i meant 614404, description updated

        Show
        Alexey Stukalov added a comment - sorry, i meant 614404, description updated
        Hide
        Scott O'Bryan added a comment -

        I notice you are using Facelets. I can only assume that is your issue. I havn't had a chance to take a look at it, but here is what I think is happening:

        StateManager changed between JSF 1.1 and JSF 1.2. While an effort was made in JSF 1.2 to allow exiting frameworks to continue to function, StateManagers written for JSF 1.1 and JSF 1.2 don't play well together. In Trinidad 1.2.6 we had to change from a JSF 1.1 type StateManager to a JSF 1.2 type StateManager in order to address some compatibility issues with the JSR 301 PortletBridge. I havn't had a chance to check yet, but my guess is that Facelets still has a JSF 1.1 compatible StateManager.

        Essentially, my guess is that saveView is being executed on the Facelet's stateManager which (if it's a JSF 1.1 statemanager) will call saveSerializedView in Trinidad's StateManagerImpl which will call saveSerializedView in the R.I.'s StateManager. When Trinidad's restoreView is being called, it does not know how to handle a state that it did not save.

        There are a number of ways this can be fixed, neither of which are difficult, but it may impact how everything works.

        1. We can implement the saveSerializedView method which is currently in the Trinidad 1.1.6 branch in addition to the saveView method which already exists in the Trinidad 1.2.6 branch. I changed both of these StateManagerImpl's to make sure the code was close to the same and the underlying logic is common among both of the StateManager's .. The reason I didn't implement this method is that (by default) in JSF 1.2, the saveSerializedView does nothing. Only if a JSF 1.1 StateManager is in the stack does this method actually return a value. So in my patch excluded implementing this method for correctness and the ability to have a consistent and predictable outcome. We can add this back in and it should fix the issue because Trinidad's state saving would once again be invoked rather then using the delegate.

        2. We can change Trinidad's StateManagerImpl to check for the existence of the String , and if the state is not a String, simply delegate to the wrapped class. This is a dangerous solution because it bypasses allows all of Trinidad's state management to be bypassed all at once.

        Show
        Scott O'Bryan added a comment - I notice you are using Facelets. I can only assume that is your issue. I havn't had a chance to take a look at it, but here is what I think is happening: StateManager changed between JSF 1.1 and JSF 1.2. While an effort was made in JSF 1.2 to allow exiting frameworks to continue to function, StateManagers written for JSF 1.1 and JSF 1.2 don't play well together. In Trinidad 1.2.6 we had to change from a JSF 1.1 type StateManager to a JSF 1.2 type StateManager in order to address some compatibility issues with the JSR 301 PortletBridge. I havn't had a chance to check yet, but my guess is that Facelets still has a JSF 1.1 compatible StateManager. Essentially, my guess is that saveView is being executed on the Facelet's stateManager which (if it's a JSF 1.1 statemanager) will call saveSerializedView in Trinidad's StateManagerImpl which will call saveSerializedView in the R.I.'s StateManager. When Trinidad's restoreView is being called, it does not know how to handle a state that it did not save. There are a number of ways this can be fixed, neither of which are difficult, but it may impact how everything works. 1. We can implement the saveSerializedView method which is currently in the Trinidad 1.1.6 branch in addition to the saveView method which already exists in the Trinidad 1.2.6 branch. I changed both of these StateManagerImpl's to make sure the code was close to the same and the underlying logic is common among both of the StateManager's .. The reason I didn't implement this method is that (by default) in JSF 1.2, the saveSerializedView does nothing. Only if a JSF 1.1 StateManager is in the stack does this method actually return a value. So in my patch excluded implementing this method for correctness and the ability to have a consistent and predictable outcome. We can add this back in and it should fix the issue because Trinidad's state saving would once again be invoked rather then using the delegate. 2. We can change Trinidad's StateManagerImpl to check for the existence of the String , and if the state is not a String, simply delegate to the wrapped class. This is a dangerous solution because it bypasses allows all of Trinidad's state management to be bypassed all at once.
        Hide
        Graeme Steyn added a comment -

        I have attached a very simple project that reproduces the problem (same attachment as TRINIDAD-880, but with the Trinidad version = 1.2.6).

        Show
        Graeme Steyn added a comment - I have attached a very simple project that reproduces the problem (same attachment as TRINIDAD-880 , but with the Trinidad version = 1.2.6).
        Hide
        Andrew Robinson added a comment -

        Added back in the JSF 1.1 deprecated functionality to support JSF
        state managers (i.e. facelets)

        SVN Rev. 630069

        Show
        Andrew Robinson added a comment - Added back in the JSF 1.1 deprecated functionality to support JSF state managers (i.e. facelets) SVN Rev. 630069

          People

          • Assignee:
            Andrew Robinson
            Reporter:
            Alexey Stukalov
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development