Action not firing before defined PhaseId

Splash Forums PrettyFaces Users Action not firing before defined PhaseId

This topic contains 13 replies, has 2 voices, and was last updated by  clemmonsm 5 years, 10 months ago.

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #18114

    clemmonsm
    Participant

    Hey guys,

    I am using the optional phaseId attribute on an action like so:

    <url-mapping id="item">
    <pattern value="/category/#{item}/" />
    <view-id value="/faces/pages/item.jspx" />
    <action phaseId="RENDER_RESPONSE">#{bean.loadItem}</action>
    </url-mapping>

    However, the method loadItem is being called after the RESTORE_VIEW phase instead of before the RENDER_RESPONSE phase. Below is my debug log which writes the end of each phase start and end. The breakpoint at line 2255 signifies the beginning of the loadItem method:

    START PHASE RESTORE_VIEW 1
    END PHASE RESTORE_VIEW 1
    START PHASE RESTORE_VIEW 1
    END PHASE RESTORE_VIEW 1
    Source breakpoint occurred at line 2255 of siteTasks.java.
    START PHASE RENDER_RESPONSE 6
    END PHASE RENDER_RESPONSE 6

    I expected to see the following, which occurs when I call the method via <f:view beforePhase=”#{bean.loadItem}”> from the jspx page:

    START PHASE RESTORE_VIEW 1

    END PHASE RESTORE_VIEW 1

    START PHASE RESTORE_VIEW 1

    END PHASE RESTORE_VIEW 1

    START PHASE RENDER_RESPONSE 6

    Source breakpoint occurred at line 2255 of siteTasks.java.

    END PHASE RENDER_RESPONSE 6

    Am I missing an additional config to activate the phaseId attribute? I am using v3.3.3 snapshot.

    #21782

    clemmonsm
    Participant

    I guess a clarification is really what I need. When using the following:

    <action phaseId="RENDER_RESPONSE">#{bean.loadItem}</action>

    …does that mean bean.loadItem is supposed to fire before the RENDER RESPONSE beforePhase() or within the RENDER RESPONSE beforePhase()?

    If it is the former, then I see that it is working as expected. If it is the latter (which is what I am hoping for), then below is the class I am using to write out the phase logging I detailed in my previous post:

    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;

    public class LifeCycleListener implements PhaseListener {

    public PhaseId getPhaseId() {
    return PhaseId.ANY_PHASE;
    }

    public void beforePhase(PhaseEvent event) {
    System.out.println("START PHASE" + event.getPhaseId());
    }

    public void afterPhase(PhaseEvent event) {
    System.out.println("END PHASE" + event.getPhaseId());
    }

    }

    #21783

    PrettyFaces itself uses a PhaseListener to trigger the page action invocation. This is done from withing beforePhase() of the phase specified by the user. I guess you are seeing this output because your phase listener is executed after the PrettyFaces phase listener.

    I hope this clears up the situation a bit! :)

    Christian

    #21784

    clemmonsm
    Participant

    So in effect, if a user defines a phaseId of RENDER RESPONSE on the page action, the action actually occurs within the RENDER RESPONSE beforePhase()? If true, the components on the jspx page should be within scope inside the method, but in actuality they are not. This makes me think the method is being called outside of the beforePhase() for RENDER RESPONSE. When I access this method using the view’s beforePhase attribute, the components are in scope.

    #21785

    Yes, if a user defines a phaseId of RENDER RESPONSE the action should be called from within beforePhase()! However I think there may be exceptions to this rule. But only if FacesContext.responseComplete() is set (which is the case only in some special cases) or if dynaview is used.

    What exactly do you mean with “components being in scope”?

    You could check if it’s really beforePhase() which executes the method by adding a “Thread.dumpStack()” to it.

    #21786

    clemmonsm
    Participant

    What exactly do you mean with “components being in scope”?

    For example, say I have a h:panelGroup component on the page item.jspx that is bound to a bean like so:

    <h:panelGroup id="pgModels" binding="#{bean.pgModels}"/>

    In my action method bean.loadItem, I attempt to dynamically add components, such as h:outputLabel or h:outputText, to the panel group pgModels.

    When I call bean.loadItem as phaseEvent method from the JSPX view tag, the h:panelGroup object, pgModels, can be accessed successfully inside of bean.loadItem and I can add components to pgModels dynamically. Here is my code for this approach:

    JSPX view tag:

    <f:view beforePhase="#{bean.loadItem}">
    ...
    </f:view>

    Bean method:

    public void loadItem(PhaseEvent phaseEvent) {
    // code here
    }

    pretty-config:

    <url-mapping id="item">
    <pattern value="/category/#{item}/" />
    <view-id value="/faces/pages/item.jspx" />
    </url-mapping>

    However, when I call loadItem using a url-mapping action, the h:panelGroup object, pgModels, is null inside loadItem. Here is my code for this configuration:

    JSPX view tag:

    <f:view>
    ...
    </f:view>

    Bean method:

    public String loadItem() {
    // code here
    }

    pretty-config:

    <url-mapping id="item">
    <pattern value="/category/#{item}/" />
    <view-id value="/faces/pages/item.jspx" />
    <action phaseId="RENDER_RESPONSE">#{bean.loadItem}</action>
    </url-mapping>

    The differing results are why I think the method is being called at different points of the lifecycle. I will add “Thread.dumpStack()” to see if I can get more info.

    Yes, if a user defines a phaseId of RENDER RESPONSE the action should be called from within beforePhase()! However I think there may be exceptions to this rule. But only if FacesContext.responseComplete() is set (which is the case only in some special cases) or if dynaview is used.

    What would the exceptions be? What would cause them? Where would one set FacesContext.responseComplete(), in the mapping action?

    #21787

    The differing results are why I think the method is being called at different points of the lifecycle. I will add “Thread.dumpStack()” to see if I can get more info.

    Could you perhaps post the result of Thread.dumpStack() for both variants? Perhaps this will give us a clue.

    What would the exceptions be? What would cause them? Where would one set FacesContext.responseComplete(), in the mapping action?

    There will be now exception. Invoking the action will simply be skipped. But this doesn’t seem to be the case in you example.

    #21788

    clemmonsm
    Participant

    Attempting to figure out how to do a Thread.dumpStack() with getting the error…

    java.lang.Exception: Stack trace

    at java.lang.Thread.dumpStack(Thread.java:1273)

    at siteUtils.siteTasks.loadCommunity(siteTasks.java:282)

    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 com.sun.el.parser.AstValue.invoke(Unknown Source)

    at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)

    at com.ocpsoft.pretty.faces.util.FacesElUtils.invokeMethod(FacesElUtils.java:70)

    at com.ocpsoft.pretty.faces.util.FacesElUtils.invokeMethod(FacesElUtils.java:62)

    at com.ocpsoft.pretty.faces.beans.ActionExecutor.executeActions(ActionExecutor.java:56)

    at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.processEvent(PrettyPhaseListener.java:131)

    at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.beforePhase(PrettyPhaseListener.java:73)

    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:279)

    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:214)

    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)

    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)

    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)

    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)

    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:205)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:106)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

    at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:271)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:177)

    at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:175)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:126)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:524)

    at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:253)

    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)

    at java.security.AccessController.doPrivileged(Native Method)

    at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)

    at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)

    at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)

    at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)

    at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)

    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)

    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)

    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)

    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)

    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)

    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)

    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)

    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

    #21789

    That’s not an error! That’s the actual output of dumpStack()! :)

    #21790

    clemmonsm
    Participant

    Ha, well in that case that’s the dumpStack from calling the method via the url-mapping action. Mobile at the moment, so I will post the other dumpStack when I return home.

    #21791

    From the stacktrace you can see that PrettyFaces correctly fires the action from beforePhase:

    at siteUtils.siteTasks.loadCommunity(siteTasks.java:282)                                            <--- your action
    [...]
    at com.ocpsoft.pretty.faces.beans.ActionExecutor.executeActions(ActionExecutor.java:56) <--- action execution
    at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.processEvent(PrettyPhaseListener.java:131)
    at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.beforePhase(PrettyPhaseListener.java:73) <--- before phase is called by JSF
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:279)
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:214) <--- some method responsible for the render phase
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)

    It would be interesting to see the other stacktrace…

    #21792

    clemmonsm
    Participant

    Here’s the stacktrace from the f:view beforePhase event:

    java.lang.Exception: Stack trace

    at java.lang.Thread.dumpStack(Thread.java:1273)

    at siteUtils.siteTasks.loadCommunity(siteTasks.java:283)

    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 com.sun.el.parser.AstValue.invoke(Unknown Source)

    at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)

    at javax.faces.component.UIViewRoot.notifyPhaseListeners(UIViewRoot.java:608)

    at javax.faces.component.UIViewRoot.notifyBefore(UIViewRoot.java:510)

    at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:564)

    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:928)

    at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:266)

    at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:197)

    at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:87)

    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:189)

    at org.apache.myfaces.trinidadinternal.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:193)

    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._renderResponse(LifecycleImpl.java:800)

    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:294)

    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:214)

    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)

    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)

    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)

    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)

    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:205)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:106)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

    at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:271)

    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:177)

    at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:175)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:126)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:524)

    at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:253)

    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)

    at java.security.AccessController.doPrivileged(Native Method)

    at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)

    at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)

    at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)

    at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)

    at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)

    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)

    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)

    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)

    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)

    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)

    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)

    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)

    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)

    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

    #21793

    Hmmm, seems like the invocation happens in a different context here:

    at java.lang.Thread.dumpStack(Thread.java:1273)
    at siteUtils.siteTasks.loadCommunity(siteTasks.java:283) <---- your method gets invoked
    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 com.sun.el.parser.AstValue.invoke(Unknown Source)
    at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)
    at javax.faces.component.UIViewRoot.notifyPhaseListeners(UIViewRoot.java:608) <---- JSF notifies the view event listeners
    at javax.faces.component.UIViewRoot.notifyBefore(UIViewRoot.java:510)
    at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:564)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:928)
    at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:266) <---- JSF renders the view
    at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:197)

    So in this case your method is actually called before the rendering occurs but WITHIN the rendering phase. That seems to be the main difference.

    Unfortunately I don’t know if we can do anything to help you with this problem. I think a PhaseListener is the only place for PrettyFaces to hook into the phase execution.

    @lincoln: any thoughts on this one?

    Christian

    #21794

    clemmonsm
    Participant

    Thank you for the insight Christian. It is not a show stopper, I can continue processing the page objects using the f:view beforePhase approach and performing the url-mapping action tasks separately without an issue. Just didn’t want to miss out on an opportunity to consolidate the two if it existed. Thanks!

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.

Comments are closed.