Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Won't Fix
-
1.2.2
-
None
-
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)