Search code examples
javajsfexceptionjsf-2glassfish-3

Debugging JSF java.lang.ClassCastException in Restore View Phase


I'd like some advice on how I may attempt to debug the cause of a JSF exception and/or know whether anyone has seen this behaviour before. I'll use the following notation to describe the problem:

  • 'A' - means viewing page A,
  • 'A, CmdLink => B' - means viewing page B after clicking on a <h:commandLink> link in page A,
  • 'A, URL => B' - means viewing page B by entering its URL in the address bar and pressing enter while viewing page A. (So JSF has still previously generated page A.)

I get the following java.lang.ClassCastException:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.Map
at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:225)
at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113)

when clicking the link in page B in the following sequence:

  • A, CmdLink => B, CmdLink => C

So the error page with the exception is displayed instead of page C. However, the following scenarios do not generate the error:

  • A, URL => B, CmdLink => C
  • D, CmdLink => B, CmdLink => C

And this sequence does not generate an error the second time, so page C is correctly displayed:

  • A, CmdLink => B, CmdLink => ErrorPage (instead of C), URL => B, CmdLink => C

The exception only occurs when page A was the previously viewed page to page B (and page B was not reached by directly entering the URL in the browser's address bar).

Page A is a complex page with multiple drop-down boxes, RichFaces components, an OpenFaces tabSet, multiple datatables, and uses RichFaces AJAX (a4j) whereas page B does not use any of these, only a simple form with command links. Both pages use the same JSF template hierarchy. (Page B is a simple edit page for one of the items listed in a datatable in a tab section on page A.)

The issue is not confined to page B being the page following page A. This sequence also gives the same exception with the error page displayed after clicking on a link in page E:

  • A, CmdLink => E, CmdLink => F

I've tried adding a phase listener with the following output produced after clicking on the link in page B:

INFO: ++++++ START PHASE RESTORE_VIEW 1 ++++++
INFO: ++++++ END PHASE RESTORE_VIEW 1 ++++++

I'm using NetBeans 7.2, Glassfish 3.1, RichFaces 4.3.3 Final, OpenFaces 3.0, and JSF 2.1.

Any useful suggestions would be appreciated as to how I may attempt to resolve this problem - thanks.


Solution

  • I've been able to resolve this problem as there was another link (call it CmdLinkA2) on Page A (in a different tab) which when followed:

    • A, CmdLinkA2 => B, CmdLink => C

    doesn't cause the above error message, and Page C is displayed correctly. Comparing the different backing bean action methods used for the problematic <h:commmandLink> and the working one (CmdLinkA2) on Page A, the String returned to the problematic CmdLink was missing ?faces-redirect=true on the end, i.e. equivalent to:

    1) <h:commandLink value="Next page" action="nextpage.xhtml" />

    instead of:

    2) <h:commandLink value="Next page" action=nextpage.xhtml?faces-redirect=true" />

    where (1) leads to the error message occurring instead of Page C.

    However, since Page A does not have any form data to submit, as discussed in this question, I now understand page-to-page navigation should not be performed using POST at all.