从myfaces切换到mojarra后的IndexOutOfBoundsException

时间:2012-05-16 10:41:37

标签: jsf-2 primefaces myfaces mojarra

我被迫从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

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

强尼

2 个答案:

答案 0 :(得分:1)

stacktrace暗示你正在使用PrimeFaces。

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

答案 1 :(得分:0)

我有完全相同的问题,很容易重现。
您可以使用以下类重现它:

验证

@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());
        }
    }
}

}

自定义组件:

<?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>

自定义组件字段中的inputText在processEvent()方法内的PreValidateEvent中添加了一个新的Validator。
如果现在连续三次按下提交按钮并出现验证错误,则抛出ArrayIndexOutOfBoundException。我试图调试并发现异常是在AttachedObjectListHolder #restoreState(FacesContext,Object)中抛出的,之后我的eclipse调试器变得疯狂......

我认为这是一个JSF Bug!

我想发表评论,但我还不准...... :(