jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [1311-FacesContextCDI] Let CDI handle #{facesContext}

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Tue, 7 Oct 2014 17:27:42 +0200

On Tue, Oct 7, 2014 at 4:27 PM, Edward Burns <edward.burns_at_oracle.com> wrote:
>>>>>> On Tue, 7 Oct 2014 00:50:23 +0200, arjan tijms <arjan.tijms_at_gmail.com> said:
> I wouldn't be surprised if there is code out there that assumes the
> instance returned by FacesContext.getCurrentInstance() is *NOT* a
> proxy. If so, that code will likely break. Do we care about that?
> Personally, yes, I do care about that. Does anyone else think this is a
> risk?

Other then reflective tricks, would there be any case where code is
even capable of determining the difference?

A proxied instance is typically a sub class of the class of the
original instance, and thus passes the instanceof test and everything.
For all intends and purposes it should be pretty much identical to the
original instance.

If code accessed private instance fields of a specific assumed
FacesContext implementation, then those would still be there but they
would be unused. Changing them would have no effect and reading them
would not give the actual value the real delegated-to instance is
using.

To clarify, the situation is conceptually simply this:

public MyClass {
    private int a;

    public void foo() {
    }
}

public MyClassProxy extends MyClass {
    private MyClass wrapped;

    public void foo() {
          wrapped.foo();
    }
}


>>>>>> On Mon, 6 Oct 2014 23:52:02 +0200, arjan tijms <arjan.tijms_at_gmail.com> said:
>
> AT>The instance is created by JSF using the existing FacesContext.getCurrentInstance()
> AT>call, so nothing changes there.
>
> Ah, so it will be the same instance as in prior JSF releases?

Indeed. FacesContext.getCurrentInstance() remains the root source of
FacesContext and it will return the existing, non-proxied version. For
this proposal no changes to this method will need to be made.

The proxy will automatically be generated by CDI -after- it calls the
dynamic producer. This happens here:

public class FacesContextProducer implements Bean<FacesContext> {

    // ...

    /**
     * Create the actual instance.
     *
     * @param creationalContext the creational context.
     * @return the Faces context.
     */
    @Override
    public FacesContext create(CreationalContext<FacesContext>
creationalContext) {
        return FacesContext.getCurrentInstance(); // returns the
normal non-proxied instance
    }

    // ...
}

See https://svn.java.net/svn/mojarra~svn/trunk/jsf-ri/src/main/java/com/sun/faces/context/FacesContextProducer.java


> AT> Another concern could be the existence of
> AT> FacesContext.setCurrentInstance(FacesContext instance).
>
> Yes, this is a valid concern, and we do indeed call that, and I'm sure
> folks outside of JSF call it. Again, do we care about breaking them?

I think we should care about this one, even though folks should maybe
not have been calling setCurrentInstance() in the first place (yes, at
OmniFaces we're guilty too).

It may be possible to address this concern by using a custom scope.
This custom scope would then be active when the FacesServlet is
processing the request, and it should allow (framework) code to
replace the current instance residing in the scope.

Kind regards,
Arjan Tijms







>
>
> Ed
>
> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
> | 23 work days til Devoxx 2014