[
https://issues.apache.org/jira/browse/MYFACES-985?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13069636#comment-13069636
]
Leonardo Uribe commented on MYFACES-985:
----------------------------------------
Doing some performance improvements I notice this old issue. Basically, the
code proposed is invalid, but just for reference I'll explain what's going on
in this case.
The general problem is about when it is valid to add components in JSF inside a
dataTable. In theory, UIData.setRowIndex do the following:
1. If the component is in row -1 (no row), take a "snapshot" of the components
that implements
EditableValueHolder, to restore them later when rows are traversed.
2. If the component is in a row, save the current state of EditableValueHolder
components.
3. Move to the selected row.
4. If no state saved found, restore EditableValueHolder components from saved
initial state.
5. If state saved found, restore EditableValueHolder components from stored
saved state.
The algorithm ignores all transient components, because they don't have state
(for example, t:inputCalendar uses a transient input component when popup mode
is enabled). The problem happens when a user try to create inside a renderer a
component that is EditableValueHolder and is not transient. In the moment the
"snapshot" is created, the component does not exists, so the initial state
cannot be created and the algorithm will fail.
I ignore the reasons why Mojarra code works, but I believe that is not
intentional. In JSF 2.1, full row component state was added to UIData, and the
same principle applies, but in that case the restriction applies to all
components. Note transient component are ignored too.
The problem is adding a non transient EditableValueHolder component inside a
dataTable row leads to a illegal state, because the initial state is unknown.
In JSF 2.0 and upper the most standard way to add a component as "structure" of
other component is use a custom component facelet tag handler. In t:dataTable,
this hack is used for detailStampRow and ajaxRowRender features. Also,
PostAddToViewEvent can be used to modify the component tree, because it occur
before markInitialState, so UIData rowStatePreserved will work well, and PSS
algorithm will deal with it gracefully.
I'll close this issue as invalid, because everything that can be done for solve
this issue was already done, and the reasons why does not work are completely
understood.
> UIData with multihierarchical children inside produces NPE
> ----------------------------------------------------------
>
> Key: MYFACES-985
> URL: https://issues.apache.org/jira/browse/MYFACES-985
> Project: MyFaces Core
> Issue Type: Bug
> Components: General
> Environment: Tomcat 5.0
> JDK 1.4
> Reporter: Andrew Kharchenko
> Assignee: Mathias Broekelmann
> Fix For: 2.0.0
>
> Attachments: UIData NPE Sample.rar
>
>
> I've found incorrect UIData behaviour under MyFaces which produces
> NullPointerException on runtime and which works fine under Sun implementation.
> Here it is:
> I have a custom component which is extentor from UIInput. This component has
> UIPanel extentor component as child which is added to children list of
> UIInput component on rendering.
> For one's turn, UIPanel extentor has one more UIInput extentor component as
> child which is added to children list of UIPanel component on rendering.
> This component works fine standalone, but when it is added to UIData, I have
> NPE on runtime. Here is the part of listing:
> java.lang.NullPointerException
> at
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:223)
> at
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
> at
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
> at
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
> at javax.faces.component.UIData.setRowIndex(UIData.java:178)
> I will also attach sample component's classes, definitions and test page if
> it will be granted after issue creation.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira