ICEfaces
  1. ICEfaces
  2. ICE-8798

Bean Getters getting called on none-rendered ace:dataTable

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.2
    • Fix Version/s: EE-3.2.0.GA, 3.3
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      ICEfaces
    • Assignee Priority:
      P1
    • Salesforce Case Reference:

      Description

      Arran: "A customer has raised an issue where they are seeing the contents of a non-active tab getters being called. I've been able to reproduce the reported behavior in an isolated test case using ICEfaces 3.2.0.

      This test consists of the default values for the tabSet and tabPane (clientSide=false, cache=none). Each tab has an h:outputText and an ace:dataTable. The behavior they are seeing is that when the first tab is rendered the getter for the list assigned to the ace:dataTable of the second tab content is called. The getter for the outputText in the second tab pane does not get called."
      1. Case11811Example.zip
        20 kB
        Arran Mccullough
      2. Case11811ExampleWAR.zip
        9.36 MB
        Arran Mccullough
      1. auction.png
        60 kB

        Activity

        Mircea Toma created issue -
        Hide
        Mircea Toma added a comment -

        Mark: "Ok, here's the relevant part of the stacktrace, which was the same for the current and non-current tabs' components:

        at org.icefaces.ace.component.datatable.DataTable.setRowIndex(DataTable.java:450)
        at org.icefaces.ace.component.datatable.DataTable.visitTree(DataTable.java:1442)
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
        at javax.faces.component.UIForm.visitTree(UIForm.java:344)
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
        at org.icefaces.impl.event.RestoreResourceDependencies.processEvent(RestoreResourceDependencies.java:24)
        at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
        at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2168)
        at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:2144)
        at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:302)
        at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:246)
        at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:812)
        at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:962)

        Basically, our code in RestoreResourceDependencies is doing a visitTree, which probably doesn't require UIData iteration, but is not setting the visitTree hint to that effect. Up until now, I've only seen state saving and restoration need to set that hint, but it looks like this is another example.

        In RestoreResourceDependencies, we call VisitContext.createVisitContext(FacesContext), and we should instead call VisitContext.createVisitContext(FacesContext context, null, Set<VisitHint> hints), with an EnumSet containing VisitHint.SKIP_ITERATION. There are a couple hints there, and SKIP_UNRENDERED might be relevant as well."

        Show
        Mircea Toma added a comment - Mark: "Ok, here's the relevant part of the stacktrace, which was the same for the current and non-current tabs' components: at org.icefaces.ace.component.datatable.DataTable.setRowIndex(DataTable.java:450) at org.icefaces.ace.component.datatable.DataTable.visitTree(DataTable.java:1442) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) at javax.faces.component.UIForm.visitTree(UIForm.java:344) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) at org.icefaces.impl.event.RestoreResourceDependencies.processEvent(RestoreResourceDependencies.java:24) at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106) at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2168) at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:2144) at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:302) at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:246) at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:812) at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:962) Basically, our code in RestoreResourceDependencies is doing a visitTree, which probably doesn't require UIData iteration, but is not setting the visitTree hint to that effect. Up until now, I've only seen state saving and restoration need to set that hint, but it looks like this is another example. In RestoreResourceDependencies, we call VisitContext.createVisitContext(FacesContext), and we should instead call VisitContext.createVisitContext(FacesContext context, null, Set<VisitHint> hints), with an EnumSet containing VisitHint.SKIP_ITERATION. There are a couple hints there, and SKIP_UNRENDERED might be relevant as well."
        Mircea Toma made changes -
        Field Original Value New Value
        Assignee Mircea Toma [ mircea.toma ]
        Arran Mccullough made changes -
        Salesforce Case Reference 5007000000PY9CaAAL
        Hide
        Arran Mccullough added a comment -

        Attached test case that demonstrates the reported behavior.

        Show
        Arran Mccullough added a comment - Attached test case that demonstrates the reported behavior.
        Arran Mccullough made changes -
        Attachment Case11811Example.zip [ 15080 ]
        Attachment Case11811ExampleWAR.zip [ 15081 ]
        Mircea Toma made changes -
        Fix Version/s 3.3 [ 10370 ]
        Assignee Priority P2 [ 10011 ]
        Ken Fyten made changes -
        Assignee Priority P2 [ 10011 ] P1 [ 10010 ]
        Ken Fyten made changes -
        Fix Version/s EE-3.2.0.GA [ 10332 ]
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #32831 Mon Dec 17 09:50:13 MST 2012 mircea.toma ICE-8798 Modified DataTable component to test for Myfaces environment before resetting the data model, whenever that was meant to fix a Myfaces issue. Also modified RestoreResourceDependencies to provide the SKIP_ITERATION hint whn visiting the tree, this way the data table will not access its data model and indirectly the backing beans.
        Files Changed
        Commit graph MODIFY /icefaces3/trunk/icefaces/ace/component/src/org/icefaces/ace/component/datatable/DataTable.java
        Commit graph MODIFY /icefaces3/trunk/icefaces/core/src/main/java/org/icefaces/impl/event/RestoreResourceDependencies.java
        Hide
        Mircea Toma added a comment -

        Modified DataTable component to test for Myfaces environment before resetting the data model, whenever that was meant to fix a Myfaces issue. Also modified RestoreResourceDependencies to provide the SKIP_ITERATION hint whn visiting the tree, this way the data table will not access its data model and indirectly the backing beans.

        Show
        Mircea Toma added a comment - Modified DataTable component to test for Myfaces environment before resetting the data model, whenever that was meant to fix a Myfaces issue. Also modified RestoreResourceDependencies to provide the SKIP_ITERATION hint whn visiting the tree, this way the data table will not access its data model and indirectly the backing beans.
        Hide
        Mircea Toma added a comment -

        The bean getters are now accessed only during apply values, process validation, update model and invoke application phases as per TabSet described behaviour:

        "When a tabSet is in server mode, and changes tabs from the old one to
        the new one, the old one is executed and the new one is rendered. In
        client mode, if the server has been contacted, they all execute. This
        method is used by the TabPane(s) to control their execution."

        Show
        Mircea Toma added a comment - The bean getters are now accessed only during apply values, process validation, update model and invoke application phases as per TabSet described behaviour: "When a tabSet is in server mode, and changes tabs from the old one to the new one, the old one is executed and the new one is rendered. In client mode, if the server has been contacted, they all execute. This method is used by the TabPane(s) to control their execution."
        Hide
        Mircea Toma added a comment -

        If we intend to go even further to use a cached data model value which will truly get rid of all the bean getter invocations the DataTable component class will need to be modified so that setRowIndex(-1) method is not called anymore. When this method is called with -1 as parameter the cached data model is cleared causing the component to recalculate its data model.

        Show
        Mircea Toma added a comment - If we intend to go even further to use a cached data model value which will truly get rid of all the bean getter invocations the DataTable component class will need to be modified so that setRowIndex(-1) method is not called anymore. When this method is called with -1 as parameter the cached data model is cleared causing the component to recalculate its data model.
        Mircea Toma made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Nils Lundquist added a comment -

        Mircea, as nice a simplification as it would be to prevent the component from ever clearing its cached model, I don't think it's task we'll be able to invest the huge amount of required time in (particularly as a speculative optimization). In addition to the question of why the model would be being cleared it if wasn't necessary for at least some situations.

        The component often checks to see if the index is -1 to handle special unindexed iterations. e.g the -1 index is the only index that causes the implementation of getClientId to return an a table ID without an index, which is particularly important as it is the key for DataTable component state. There are many place in state saving and visiting that the 'unset' index is required.

        In addition setRowIndex(-1) called throughout the UIData superclass implementations of the MyFaces and Mojarra. Though large parts of these have been overridden, a very large time investment would need to be made to override the rest of these cases (in a way appropriate for both impls), and remove setRowIndex, substitute some new mechanism in the logic, and then test both MyFaces and Mojarra throughly.

        I wouldn't suggest pursuing redevelopment of such a quirk-filled and wide reaching UIData API feature unless absolutely necessary.

        Show
        Nils Lundquist added a comment - Mircea, as nice a simplification as it would be to prevent the component from ever clearing its cached model, I don't think it's task we'll be able to invest the huge amount of required time in (particularly as a speculative optimization). In addition to the question of why the model would be being cleared it if wasn't necessary for at least some situations. The component often checks to see if the index is -1 to handle special unindexed iterations. e.g the -1 index is the only index that causes the implementation of getClientId to return an a table ID without an index, which is particularly important as it is the key for DataTable component state. There are many place in state saving and visiting that the 'unset' index is required. In addition setRowIndex(-1) called throughout the UIData superclass implementations of the MyFaces and Mojarra. Though large parts of these have been overridden, a very large time investment would need to be made to override the rest of these cases (in a way appropriate for both impls), and remove setRowIndex, substitute some new mechanism in the logic, and then test both MyFaces and Mojarra throughly. I wouldn't suggest pursuing redevelopment of such a quirk-filled and wide reaching UIData API feature unless absolutely necessary.
        Hide
        Carmen Cristurean added a comment - - edited

        Re-opening due to errors that occur when running the samples' tests in automation.
        In automation, the first test in the test suite fails because of an HTTP error 500 (see also attachment):
        HTTP Status 500 -

        type Exception report

        message

        description The server encountered an internal error () that prevented it from fulfilling this request.

        exception

        java.lang.NullPointerException
        javax.faces.component.UIViewRoot$ViewMap.clear(UIViewRoot.java:1779)
        com.sun.faces.config.InitFacesContext.release(InitFacesContext.java:239)
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:577)
        note The full stack trace of the root cause is available in the Apache Tomcat/6.0.26 logs.

        In tomcat log, the error is:
        17-Dec-2012 4:14:08 PM org.apache.catalina.core.StandardWrapperValve invoke
        SEVERE: Servlet.service() for servlet Faces Servlet threw exception
        java.lang.NullPointerException
        at javax.faces.component.UIViewRoot$ViewMap.clear(UIViewRoot.java:1779)
        at com.sun.faces.config.InitFacesContext.release(InitFacesContext.java:239)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:577)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)

        This error is not an issue when deploying/testing manually.

        Show
        Carmen Cristurean added a comment - - edited Re-opening due to errors that occur when running the samples' tests in automation. In automation, the first test in the test suite fails because of an HTTP error 500 (see also attachment): HTTP Status 500 - type Exception report message description The server encountered an internal error () that prevented it from fulfilling this request. exception java.lang.NullPointerException javax.faces.component.UIViewRoot$ViewMap.clear(UIViewRoot.java:1779) com.sun.faces.config.InitFacesContext.release(InitFacesContext.java:239) javax.faces.webapp.FacesServlet.service(FacesServlet.java:577) note The full stack trace of the root cause is available in the Apache Tomcat/6.0.26 logs. In tomcat log, the error is: 17-Dec-2012 4:14:08 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet Faces Servlet threw exception java.lang.NullPointerException at javax.faces.component.UIViewRoot$ViewMap.clear(UIViewRoot.java:1779) at com.sun.faces.config.InitFacesContext.release(InitFacesContext.java:239) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:577) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:662) This error is not an issue when deploying/testing manually.
        Carmen Cristurean made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Carmen Cristurean made changes -
        Attachment auction.png [ 15182 ]
        Hide
        Ken Fyten added a comment -

        Note that this revision is when the failures begin in automation.

        Show
        Ken Fyten added a comment - Note that this revision is when the failures begin in automation.
        Ken Fyten made changes -
        Summary Bean getters called on inactive tab Bean Getters getting called on none-rendered ace:dataTable
        Hide
        Carmen Cristurean added a comment - - edited

        The same errors occur when running in automation the ACE tests, 3.0 Regression tests, or the tutorials' tests.

        Show
        Carmen Cristurean added a comment - - edited The same errors occur when running in automation the ACE tests, 3.0 Regression tests, or the tutorials' tests.
        Hide
        Mircea Toma added a comment -

        This NullPointerException is not caused by our code. It is most probably a Mojarra thread related issue regarding how FacesContext is setup at the application startup. The InitFacesContext implementation is used only on application startup, ICEfaces doesn't even get a chance to run. When the ViewMap is cleared it seems the current FacesContext is not set.

        Also, this exception occurred well before the last fix for ICE-8798 was checked in, see ICE-8752. I believe this last problem should be pursued as a separate JIRA case.

        Show
        Mircea Toma added a comment - This NullPointerException is not caused by our code. It is most probably a Mojarra thread related issue regarding how FacesContext is setup at the application startup. The InitFacesContext implementation is used only on application startup, ICEfaces doesn't even get a chance to run. When the ViewMap is cleared it seems the current FacesContext is not set. Also, this exception occurred well before the last fix for ICE-8798 was checked in, see ICE-8752 . I believe this last problem should be pursued as a separate JIRA case.
        Hide
        Mircea Toma added a comment -

        Created follow up issue for the NPE problem: ICE-8851

        Show
        Mircea Toma added a comment - Created follow up issue for the NPE problem: ICE-8851
        Mircea Toma made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Mircea Toma
          • Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: