eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
162 stars 110 forks source link

Restore state - java.lang.InstantiationException: com.sun.faces.facelets.el.ContextualCompositeMethodExpression$SetClientIdListener #4945

Closed wklaczynski closed 2 years ago

wklaczynski commented 3 years ago

An exception occurred when restoring the state.

Caused by: java.lang.InstantiationException: com.sun.faces.facelets.el.ContextualCompositeMethodExpression$SetClientIdListener
    at java.base/java.lang.Class.newInstance(Class.java:639)
    at javax.faces.api@3.0.0.SP01//javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:130)

In order for the state to restore, the class should have a static and public modifier.

    public static class SetClientIdListener implements ComponentSystemEventListener {

        private ContextualCompositeMethodExpression ccME;

        public SetClientIdListener() {
        }

        public SetClientIdListener(ContextualCompositeMethodExpression ccME) {
            this.ccME = ccME;
        }

        @Override
        public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
            ccME.ccClientId = event.getComponent().getClientId();
            event.getComponent().unsubscribeFromEvent(PostAddToViewEvent.class, this);
        }
    }

Unfortunately, this bug is in both JSF2.3 and 3.0.

BalusC commented 2 years ago

Problem is understood but a minimal reproducer would be very helpful in order to create an integration test.

So far I haven't been able to reproduce this in Mojarra 2.3.17 on Tomcat 9.0.56 in the smallest possible project with everything configured to the absolute minimum (i.e. web.xml, faces-config.xml and beans.xml files are basically empty).

View:

<!DOCTYPE html>
<html
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:my="http://xmlns.jcp.org/jsf/composite/components"
>
    <h:body>
        <h:form>
            <my:component action="#{bean.submit}" />
        </h:form>
    </h:body>
</html>

resources/components/component.xhtml

<ui:component
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:cc="http://xmlns.jcp.org/jsf/composite"
>
    <cc:interface>
        <cc:attribute name="action" method-signature="String method()" />
    </cc:interface>
    <cc:implementation>
        <h:commandButton value="Submit" action="#{cc.attrs.action}" />
    </cc:implementation>
</ui:component>

Model:

package com.example;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class Bean {

    public void submit() {
        System.out.println("Bean.submit()");
    }
}

I suspect you have configured something related to state saving in web.xml, but even with all state saving defaults flipped the other side as below,

    <context-param>
        <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>

I still cannot reproduce it.

BalusC commented 2 years ago

Any luck, @wklaczynski ?

BalusC commented 2 years ago

Norepro and nofeedback, closing off.