MyFaces Core
  1. MyFaces Core
  2. MYFACES-3246

java.lang.IndexOutOfBoundsException when CACHE_EL=always

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0.8, 2.1.2
    • Component/s: None
    • Labels:
      None
    • Environment:
      myfaces core trunk

      Description

      java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
      at java.util.ArrayList.RangeCheck(ArrayList.java:547)
      at java.util.ArrayList.get(ArrayList.java:322)
      at org.apache.myfaces.view.facelets.impl.DefaultFaceletContext.getTemplateContext(DefaultFaceletContext.java:632)
      at org.apache.myfaces.view.facelets.impl.DefaultFaceletContext.isAllowCacheELExpressions(DefaultFaceletContext.java:831)
      at org.apache.myfaces.view.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:426)
      at org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler.applyAttachedObject(AjaxHandler.java:391)
      at org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler.apply(AjaxHandler.java:218)

        Activity

        Hide
        Leonardo Uribe added a comment -

        Could you provide an example about how to reproduce it?

        Show
        Leonardo Uribe added a comment - Could you provide an example about how to reproduce it?
        Hide
        Martin Kočí added a comment -

        Reproducible with this structure:

        main.xhtml (viewRoot): <ui:include src="/included1.xhtml" /> <!-- 1. include -->

        included1.xhtml:
        <ui:include src="included2.xhtml" /> <!-- 2. include -->
        <h:commandButton>
        <f:ajax execute="@this" />
        </h:commandButton>

        included2.xhtml : anything

        Show
        Martin Kočí added a comment - Reproducible with this structure: main.xhtml (viewRoot): <ui:include src="/included1.xhtml" /> <!-- 1. include --> included1.xhtml: <ui:include src="included2.xhtml" /> <!-- 2. include --> <h:commandButton> <f:ajax execute="@this" /> </h:commandButton> included2.xhtml : anything
        Hide
        Martin Kočí added a comment -

        Here is the complete minimized source:

        main.xhtml:

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
        <html>
        <h:head />
        <h:body> <ui:include src="included1.xhtml" /></h:body>
        </html>
        </f:view>

        included1.xhtml:

        <f:subview xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
        <ui:include src="included2.xhtml" />
        <h:commandButton> <f:ajax execute="@this" /> </h:commandButton>
        </f:subview>

        included2.xhtml

        <f:subview xmlns:f="http://java.sun.com/jsf/core" />

        Show
        Martin Kočí added a comment - Here is the complete minimized source: main.xhtml: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <html> <h:head /> <h:body> <ui:include src="included1.xhtml" /></h:body> </html> </f:view> included1.xhtml: <f:subview xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <ui:include src="included2.xhtml" /> <h:commandButton> <f:ajax execute="@this" /> </h:commandButton> </f:subview> included2.xhtml <f:subview xmlns:f="http://java.sun.com/jsf/core" />
        Hide
        Leonardo Uribe added a comment -

        Thanks for the example. It helps a lot to create a JUnit test using the wonderful FaceletTestCase base class and fix this one quickly. Just create the files, add some lines of code and that's it!.

        The problem is related to FaceletContext.FACELET_CONTEXT_KEY. This key by historical reasons is assigned on the constructor of DefaultFaceletContext, but this is not good, because in some cases like ui:include, we should revert to the previous context as soon as the tag has been applied. So, this key should be put and restored on the places where a DefaultFaceletContext is created. AjaxHandler.applyAttachedObject retrieve a FaceletContext instance from this key, so if you move the button before ui:include it will work.

        Show
        Leonardo Uribe added a comment - Thanks for the example. It helps a lot to create a JUnit test using the wonderful FaceletTestCase base class and fix this one quickly. Just create the files, add some lines of code and that's it!. The problem is related to FaceletContext.FACELET_CONTEXT_KEY. This key by historical reasons is assigned on the constructor of DefaultFaceletContext, but this is not good, because in some cases like ui:include, we should revert to the previous context as soon as the tag has been applied. So, this key should be put and restored on the places where a DefaultFaceletContext is created. AjaxHandler.applyAttachedObject retrieve a FaceletContext instance from this key, so if you move the button before ui:include it will work.
        Hide
        Martin Kočí added a comment -

        Thanks Leo, I'm going to do performance tests with this CACHE_EL=always now ...

        Show
        Martin Kočí added a comment - Thanks Leo, I'm going to do performance tests with this CACHE_EL=always now ...

          People

          • Assignee:
            Leonardo Uribe
            Reporter:
            Martin Kočí
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development