[ https://issues.apache.org/jira/browse/MYFACES-1820?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12585057#action_12585057 ]
Simon Kitching commented on MYFACES-1820: ----------------------------------------- Actually, this problem exists for every class in the JSF spec that is meant to be decorated. They all share this common design flaw. The solution attached for FacesContext works, but cannot be applied to other classes (they do not have a setInstance method). It would be nice to have a consistent solution for every decorated class. One solution would be for the "impl" classes for all of these decoratable classes to always set a request-scoped var when they are created, called {class}:DFLT_INSTANCE or similar. Then the api base class for each of these can look for the request-scoped var and delegate. > Infinite loop can occur when custom FacesContext subclass compiled against > JSF1.1 but used with JSF1.2 > ------------------------------------------------------------------------------------------------------ > > Key: MYFACES-1820 > URL: https://issues.apache.org/jira/browse/MYFACES-1820 > Project: MyFaces Core > Issue Type: Bug > Components: JSR-252 > Affects Versions: 1.2.2 > Reporter: Simon Kitching > Attachments: FacesContext.patch.txt, patch-1820.txt > > > 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) -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.