0

I was forced to switch from myfaces (2.1.7) to mojarra (2.1.7). After this I'm getting exceptions like this one below all over the place.

I'm submitting a form, that gives me validation errors. This is correct so far. I submit the form again, that gives me validation errors. This is correct so far. Now I submit the form again and I get the 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

I googled this, but haven't found any clue yet.

Jonny

user871611
  • 3,307
  • 7
  • 51
  • 73

2 Answers2

1

The stacktrace hints that you're using PrimeFaces.

This problem is known in older versions of PrimeFaces and is actually a bug in PrimeFaces, not in Mojarra. Make sure that you're using the latest PrimeFaces version. As of now that's 2.2.1 when you're using PF2 or 3.2 when you're using PF3.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi BalusC, thanks for your quichk reply. I saw this issue, but I don't think its this. I'm using PF3.2. I narrowed it down, that when I'm using `` like this ` ` I'm running into this error. Removing the disabling-validation stuff _solves_ it. I'm puzzled. – user871611 May 16 '12 at 13:08
  • I've ran into the same problem yesterday, and had to search a long time to fix this. I hope people find this page when they need to, because the problem IS caused by the validateBean component. It is not required to remove the tag, but you will need to refresh your page before entering another transition. One way to do this is to add " ajax='false' " to the commandbutton that submits the form. Hopefully this will help someone in the future :) –  Nov 20 '12 at 08:30
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... :(

Lusk116
  • 791
  • 1
  • 6
  • 17