myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Leonardo Uribe (JIRA)" <...@myfaces.apache.org>
Subject [jira] Commented: (MYFACES-1820) Infinite loop can occur when custom FacesContext subclass compiled against JSF1.1 but used with JSF1.2
Date Thu, 17 Dec 2009 21:32:18 GMT

    [ https://issues.apache.org/jira/browse/MYFACES-1820?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12792138#action_12792138
] 

Leonardo Uribe commented on MYFACES-1820:
-----------------------------------------

Just as a side note, the latest code in trunk looks like this: 

    public ELContext getELContext()
    {
        // Do NOT use getCurrentInstance here. For FacesContext decorators that
        // register themselves as "the current instance" that will cause an
        // infinite loop. For FacesContext decorators that do not register
        // themselves as "the current instance", if they are themselves wrapped
        // by a decorator that *does* register itself, then an infinite loop
        // also occurs.
        //
        // As noted above, we really want to do something like
        //   ctx = getWrappedInstance();
        // where the subclass can return the object it is delegating to. 
        // As there is no such method, however, the best we can do is pass the
        // method call on to the first-registered FacesContext instance. That
        // instance will never be "this", as the real original FacesContext
        // object will provide a proper implementation of this method.
        FacesContext ctx = _firstInstance.get();

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

        ELContext elctx = ctx.getELContext();

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

        return elctx;
    }

maybe we could add an check for equals to prevent the infinite loop:

if (ctx == this)
{
    throw new UnsupportedOperationException();
}

I remember this error usually happens when FacesContext instances not implementing this method
are called, but the current version should works.


> 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.


Mime
View raw message