0

我被迫从 myfaces (2.1.7) 切换到 mojarra (2.1.7)。在此之后,我在下面到处都是这样的例外。

我正在提交一个表单,它给了我验证错误。到目前为止这是正确的。我再次提交表单,这给了我验证错误。到目前为止这是正确的。现在我再次提交表单,我得到了 IndexOutOfBoundsException。

javax.faces.FacesException: Unexpected error restoring state for component with id someForm:someField.  Cause: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1.
    at com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:272)
    at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1612)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at javax.faces.component.UIForm.visitTree(UIForm.java:371)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:251)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:453)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:142)
    at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    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:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at javax.faces.component.AttachedObjectListHolder.restoreState(AttachedObjectListHolder.java:165)
    at javax.faces.component.UIInput.restoreState(UIInput.java:1411)
    at com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:264)
    ... 35 more

我用谷歌搜索了这个,但还没有找到任何线索。

强尼

4

2 回答 2

1

堆栈跟踪提示您正在使用 PrimeFaces。

这个问题在旧版本的 PrimeFaces 中是已知的,实际上是 PrimeFaces 中的错误,而不是 Mojarra 中的错误。确保您使用的是最新的PrimeFaces 版本。截至目前,当您使用 PF2 时为 2.2.1,当您使用 PF3 时为 3.2。

于 2012-05-16T12:29:16.480 回答
0

I have the exact same problem and it is easy to reproduce.
You can reproduce it with the following classes:

Validator:

@FacesValidator("testValidator")
public class TestValidator implements Validator {

    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {
        if (!(o instanceof Integer)) {
            throw new ValidatorException(new FacesMessage("validation message!"));
        }
    }
}

FacesComponent:

@ListenerFor(systemEventClass = PreValidateEvent.class)
@FacesComponent("testField")
public class TestField extends UIComponentBase implements NamingContainer {

@Override
public String getFamily() {
    return UINamingContainer.COMPONENT_FAMILY;
}

@Override
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
    super.processEvent(event);
    UIComponent findComponent = findComponent("input");
    if (findComponent instanceof UIInput) {
        UIInput i = (UIInput) findComponent;
        boolean notFound = true;
        for (Validator v : i.getValidators()) {
            if (v instanceof TestValidator) {
                notFound = false;
            }
        }
        if (notFound) {
            i.addValidator(new TestValidator());
        }
    }
}

}

Custom Component:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite">

    <!-- INTERFACE -->
    <cc:interface componentType="testField">
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        field: <h:inputText id="input" value="#{testController.inputText}" />
    </cc:implementation>
</html>

ManagedBean:

@SessionScoped
@Named("testController")
public class TestController implements Serializable {

private static final long serialVersionUID = 1L;

private String inputText = "";

public TestController() {
}

public void actionListener(ActionEvent event) {

}

public String myAction() {
    return "";
}

public String getInputText() {
    return inputText;
}

public void setInputText(String inputText) {
    this.inputText = inputText;
}

}

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:t="http://java.sun.com/jsf/composite/test"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Jsf Problem</title>
    </h:head>
    <h:body>
        <h:form>    
            <h:messages />
            <t:field />
            <h:commandButton value="Submit" action="#{testController.myAction()}" />
        </h:form>
    </h:body>
</html>

The inputText inside the custom component field gets an new Validator added at PreValidateEvent inside the processEvent() method.
If the submit button is now pressed three times in a row with an validation error the ArrayIndexOutOfBoundException will be thrown. I tried to debug and found out that the exception is throwed inside AttachedObjectListHolder#restoreState(FacesContext, Object), afterward my eclipse debugger got crazy...

I think this is a JSF Bug!

I wanted to leave a comment but I'am not allowed yet... :(

于 2014-10-17T08:23:47.140 回答