Uploaded image for project: 'MyFaces Core'
  1. MyFaces Core
  2. MYFACES-1820

Infinite loop can occur when custom FacesContext subclass compiled against JSF1.1 but used with JSF1.2

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Won't Fix
    • 1.2.2
    • None
    • JSR-252
    • None

    Description

      The problem is method FacesContext.getELContext. JSF1.2 added a method to this base class that was not there in JSF1.1. This makes life difficult for existing JSF1.1 code that already subclasses that class.

      A default concrete implementation needs to exist, in order not to break existing JSF1.1 code, but (a) the current one gets it wrong, and (b) defining a correct one is difficult (impossible?)

      (1) Stan Silvert initially defined this method like this:

      // The following concrete method was added for JSF 1.2.
      // It supplies a default
      // implementation that throws UnsupportedOperationException.
      // This allows old FacesContext implementations to still work.
      public ELContext getELContext() {
      throw new UnsupportedOperationException();
      }

      (2) Dennis Byrne changed it to its current form:

      public ELContext getELContext() {
      FacesContext ctx = getCurrentInstance();

      if (ctx == null)
      throw new NullPointerException(FacesContext.class.getName());

      ELContext elctx = ctx.getELContext();

      if (elctx == null)
      throw new UnsupportedOperationException();

      return elctx;
      }

      However (2) assumes that custom subclasses never set themselves as the current instance, instead only ever delegating to the "real" instance.
      If someone's custom subclass of FacesContext ever calls setCurrentInstance(this), then an infinite loop will occur here.

      And in fact, this is just what we get:

      java.lang.StackOverflowError
      at java.lang.ThreadLocal$ThreadLocalMap.getEntry(ThreadLocal.java:357)
      at java.lang.ThreadLocal$ThreadLocalMap.access$000(ThreadLocal.java:242)
      at java.lang.ThreadLocal.get(ThreadLocal.java:127)
      at javax.faces.context.FacesContext.getCurrentInstance(FacesContext.java:98)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:35)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)
      at javax.faces.context.FacesContext.getELContext(FacesContext.java:40)

      Attachments

        1. FacesContext.patch.txt
          5 kB
          Simon Kitching
        2. patch-1820.txt
          3 kB
          Simon Kitching

        Activity

          People

            Unassigned Unassigned
            skitching Simon Kitching
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: