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

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

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 25 Sep 2014 11:36:54 -0500

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