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

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: [527-InjectFacesContext] Support and review

From: Neil Griffin <neil.griffin_at_portletfaces.org>
Date: Thu, 25 Sep 2014 12:58:42 -0400

The JSF Portlet Bridge will make beans annotated with javax.faces.bean.RequestScoped survive from the ACTION_PHASE to the RENDER_PHASE.

But CDI does not do that. If a JSF portlet developer annotates a bean with javax.enterprise.context.RequestScoped, then CDI creates a new bean in both the ACTION_PHASE and RENDER_PHASE.

If there is a successor to JSR 329, then one of the requirements for that new JSR *might* be to re-define the behavior of javax.enterprise.context.RequestScoped.

On Sep 25, 2014, at 12:36 PM, Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:

> Hi
>
> I know that the trick using @RequestScoped works, but
> Is there a 1-1 relationship between FacesContext lifecycle
> and the request lifecycle? That works fine on servlets but
> it doesn't on portlets (action request / render request).
>
> It is possible to imagine other scenarios where this
> assumption just fail. In my opinion, we should take the
> long route, create a CDI scope and use that scope to
> store the producer, so it get the right instance. After all
> JSF should be in control of FacesContext lifecycle.
>
> regards,
>
> Leonardo Uribe
>
>
> 2014-09-25 11:02 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com>:
>> Hi,
>>
>> On Thu, Sep 25, 2014 at 4:32 PM, Edward Burns <edward.burns_at_oracle.com> wrote:
>>> Arjan, can you take the action item to investigate this and report back
>>> to the group? Such investigations and reports are the bread and butter
>>> of expert group membership and really add significant value because the
>>> results the produce are so actionable.
>>
>> I took a quick look, and the results are rather interesting.
>>
>> First of all, the feature is described here:
>> http://docs.jboss.org/seam/3/servlet/latest/reference/en-US/html/injectablerefs.html#injectablerefs.http_servlet_request
>>
>> The producer was created by CDI wizards Dan Allen and Nicklas
>> Karlsson, and for the HttpServletRequest it looks as follows:
>>
>> @Produces
>> @Typed(HttpServletRequest.class)
>> @RequestScoped
>> protected HttpServletRequest getHttpServletRequest() {
>> return holder.getHttpServletRequest();
>> }
>>
>> See: http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.seam.servlet/seam-servlet/3.1.0.Beta2/org/jboss/seam/servlet/http/ImplicitHttpServletObjectsProducer.java?av=f
>>
>> The holder is an application scoped bean, which has as its main goal
>> to collect and hold on to among others the HttpServletRequest via a
>> thread local. Collection happens via a CDI event and the listeners
>> stores the request object into TLS via a wrapper. Abbreviated it's:
>>
>> protected void requestInitialized(@Observes @Initialized final
>> InternalServletRequestEvent e) {
>> ServletRequest req = e.getServletRequest();
>> // code omitted
>> requestCtx.set(new HttpServletRequestContext(req));
>> }
>>
>> See: http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.seam.servlet/seam-servlet/3.1.0.Beta2/org/jboss/seam/servlet/event/ImplicitServletObjectsHolder.java#70
>>
>> But the wrapper doesn't play a role in injection, since when the
>> producer asks the holder for the request instance, it's unwrapped
>> again. Abbreviated it's:
>>
>> public HttpServletRequest getHttpServletRequest() {
>> // code omitted
>> return HttpServletRequestContext.class.cast(requestCtx.get()).getRequest();
>> }
>>
>> See: http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.seam.servlet/seam-servlet/3.1.0.Beta2/org/jboss/seam/servlet/event/ImplicitServletObjectsHolder.java#128
>>
>> So there's not a lot of magic going at all. The key seems to be that
>> the producer itself is @RequestScoped, but the instance it produces
>> doesn't seem to be a request scoped wrapper bean at all, just the
>> normal instance. I do wonder a bit why they choose TLS storage instead
>> of a request scoped bean, but that's beside the issue here.
>>
>> As JSF already stores the FacesContext in TLS, the entire holder
>> construct isn't needed and seemingly the producer would only need to
>> be annotated with @RequestScoped.
>>
>> Kind regards,
>> Arjan