[
https://issues.apache.org/jira/browse/MYFACES-4776?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18140856#comment-18140856
]
Thomas Andraschko commented on MYFACES-4776:
--------------------------------------------
Please see https://github.com/jakartaee/faces/pull/2267
> Restoring a component value set to an unmodifiable List fails with "Could not
> restore StateHolder"
> --------------------------------------------------------------------------------------------------
>
> Key: MYFACES-4776
> URL: https://issues.apache.org/jira/browse/MYFACES-4776
> Project: MyFaces Core
> Issue Type: Bug
> Affects Versions: 4.1.5
> Reporter: Bauke Scholtz
> Priority: Major
>
> A {{List}} without a public zero-argument constructor, such as
> {{List.of(...)}}, which Java code sets as the value of a component, cannot be
> restored. The next postback fails with HTTP 500.
> h3. Reproducer
> {code:xml}
> <h:form id="form">
> <h:dataTable id="table" var="item">
> <h:column><h:outputText value="#{item}" /></h:column>
> </h:dataTable>
> <h:commandButton id="set" value="Set" action="#{bean.setValue}" />
> <h:commandButton id="submit" value="Submit" />
> </h:form>
> {code}
> {code:java}
> @Named
> @RequestScoped
> public class Bean {
> public void setValue() {
> ((UIData)
> FacesContext.getCurrentInstance().getViewRoot().findComponent("form:table")).setValue(List.of("b",
> "a", "b"));
> }
> }
> {code}
> # Click Set. The table shows the rows {{b}}, {{a}} and {{b}}.
> # Click Submit.
> h3. Expected
> The table shows the same rows.
> h3. Actual
> HTTP 500:
> {noformat}
> java.lang.IllegalStateException: Error restoring component: form:table
> at
> org.apache.myfaces.view.facelets.PartialStateManagementStrategy.restoreStateFromMap(PartialStateManagementStrategy.java:892)
> ...
> Caused by: java.lang.RuntimeException: Could not restore StateHolder of type
> java.util.ImmutableCollections$ListN (missing no-args constructor?)
> at
> jakarta.faces.component.UIComponentBase.restoreAttachedState(UIComponentBase.java:1821)
> at
> jakarta.faces.component._DeltaStateHelper.restoreState(_DeltaStateHelper.java:729)
> at
> jakarta.faces.component.UIComponentBase.restoreState(UIComponentBase.java:2064)
> at jakarta.faces.component.UIData.restoreState(UIData.java:1206)
> Caused by: java.lang.InstantiationException:
> java.util.ImmutableCollections$ListN
> Caused by: java.lang.NoSuchMethodException:
> java.util.ImmutableCollections$ListN.<init>()
> {noformat}
> Reproduced on MyFaces 4.1.5-SNAPSHOT on Tomcat 11, with server side state
> saving. With {{new ArrayList<>(List.of("b", "a", "b"))}} it works.
> h3. Cause
> {{UIComponentBase.saveAttachedState()}} saves every {{Collection}} other than
> an {{ArrayList}} together with its class:
> {code:java}
> return new _AttachedCollectionStateWrapper(attachedObject.getClass(), lst);
> {code}
> {{UIComponentBase.restoreAttachedState()}} then creates a new instance of
> that class:
> {code:java}
> restoredList = (Collection) clazz.newInstance();
> {code}
> That needs a public zero-argument constructor, which the unmodifiable
> collections of the JDK do not have. They cannot be filled through {{add()}}
> either.
> h3. Spec
> The javadoc of {{UIComponentBase.saveAttachedState()}}:
> {quote}
> This method supports saving attached objects of the following type:
> {{Object}}s, {{null}} values, and {{Collection}}s of these objects. If any
> contained objects are not {{Collection}}s and do not implement
> {{StateHolder}}, they must have zero-argument public constructors.
> {quote}
> The javadoc of {{UIComponentBase.restoreAttachedState()}}:
> {quote}
> This method supports restoring all attached objects types supported by
> {{saveAttachedState}}.
> {quote}
> A {{Collection}} is supported, and the zero-argument constructor is required
> only of the objects it contains, not of the collection itself.
> h3. Proposed fix
> In {{restoreAttachedState()}}, when the saved collection class has no
> accessible zero-argument constructor, fall back to a collection of the same
> kind: an {{ArrayList}} for a {{List}}, a {{LinkedHashSet}} for a {{Set}}, and
> an {{ArrayList}} otherwise.
> TCK: {{Issue6125IT.testUnmodifiableValueSetWholeIsRestored}} of the Jakarta
> Faces 5.0 TCK
> ([jakartaee/faces#2267|https://github.com/jakartaee/faces/pull/2267]).
> 🤖 Generated with Claude Opus 5.5
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)