chkal/pf-issue-test — Issue #31: Actions not working with MyFaces 1.1.4 and PF1.1.2
Author: chkal
Created: 2012-03-06 07:19:57+00:00
State: open

Originally filed by **lincolnb...@gmail.com** on 2010-02-18T16:33:06

Google Code issue: http://code.google.com/p/prettyfaces/issues/detail?id=30

The issue was that I was unable to get the element to work
with MyFaces-1.1.4 with ocpsoft-pretty-faces-1.1.2.jar.

Here's an excerpt my pretty-config.xml
---

/test
#{test.runTheReport}

---

My first issue was that I was getting an NPE in the method isPostBack
in FacesStateUtils

java.lang.NullPointerException
at com.ocpsoft.pretty.util.FacesStateUtils.isPostback
(FacesStateUtils.java:39)
at com.ocpsoft.pretty.beans.ActionExecutor.executeActions
(ActionExecutor.java:42)
at com.ocpsoft.pretty.event.PrettyPhaseListener.processEvent
(PrettyPhaseListener.java:69)
at com.ocpsoft.pretty.event.PrettyPhaseListener.afterPhase
(PrettyPhaseListener.java:57)
at
org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter
(PhaseListenerManager.java:89)
at org.apache.myfaces.lifecycle.LifecycleImpl.restoreView
(LifecycleImpl.java:181)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute
(LifecycleImpl.java:66)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:
137)

I fixed that with calling the following method from one of my setter
methods:

-----
public static void prettyFacesFix) {
FacesContext facesContext = FacesContext.getCurrentInstance();
Map requestScope = (Map)
facesContext.getApplication().createValueBinding("#
{requestScope}").getValue(
facesContext);
requestScope.put("ispostback",true);
}
-----

I then encountered a bug where PrettyFaces was looking for an action
method with a single Object method and then invoking that method
without parameters. I tracked this down to

com.ocpsoft.pretty.utilFacesElUtil.invokeMethod()

com.ocpsoft.pretty.PrettyException: Exception occurred while
processing Exception while invoking
expression #{test.runTheReport}
at com.ocpsoft.pretty.beans.ActionExecutor.executeActions
(ActionExecutor.java:59)
at com.ocpsoft.pretty.event.PrettyPhaseListener.processEvent
(PrettyPhaseListener.java:69)
at com.ocpsoft.pretty.event.PrettyPhaseListener.afterPhase
(PrettyPhaseListener.java:57)
at
org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter
(PhaseListenerManager.java:89)
at org.apache.myfaces.lifecycle.LifecycleImpl.restoreView
(LifecycleImpl.java:181)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute
(LifecycleImpl.java:66)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:
137)
Caused by: javax.faces.el.EvaluationException: Exception while
invoking expression #{pbrReportBean.runReport}
at org.apache.myfaces.el.MethodBindingImpl.invoke
(MethodBindingImpl.java:165)
at com.ocpsoft.pretty.util.FacesElUtils.invokeMethod
(FacesElUtils.java:53)
at com.ocpsoft.pretty.beans.ActionExecutor.executeActions
(ActionExecutor.java:46)
... 74 more
Caused by: java.lang.IllegalArgumentException: wrong number of
arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.myfaces.el.MethodBindingImpl.invoke
(MethodBindingImpl.java:129)

Here's the original method:
----
public Object invokeMethod(final FacesContext context, final
String expression) throws ELException
{
MethodBinding methodBinding =
context.getApplication().createMethodBinding(expression,
new Class[] { Object.class });
return methodBinding.invoke(context, new Class[] {});
}
----

As you can see, the first method will always fail because it looks for
a method with a single parameter of type Object and then executes it
without parameters.

Here's my patch:
----
public Object invokeMethod(final FacesContext context, final
String expression) throws ELException
{
MethodBinding methodBinding =
context.getApplication().createMethodBinding(expression,
new Class[] { });
return methodBinding.invoke(context, new Class[] {});
}
----

If there is a better way to fix all this please let me know.

Thanks,

Justin