Details
-
Type: Bug
-
Status: Closed
-
Priority: 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."
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."
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."