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

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

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Thu, 25 Sep 2014 23:56:39 +0200

Hi,

On Thu, Sep 25, 2014 at 6:58 PM, Neil Griffin <neil.griffin_at_portletfaces.org
> wrote:

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

I have to admit I know almost nothing about Portlets, but if I understand
correctly this is thus a general problem
with javax.enterprise.context.RequestScoped and Portlets, and not
specifically with injecting a request scoped FacesContext, right?

But in this case would it really matter? If a single CDI request scope does
not survive beyond the Portlet action phase and into the render phase, then
there would simply be one additional call to
FacesContext#getCurrentInstance if the proxy is referenced again in the
render phase, right? This then grabs the current FacesContext according to
the existing JSF rules and all should be right again. Or am I missing
something obvious?


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

Just wondering, but isn't JSR 329 specifically designed for
interoperability with JSF 1.2 only?

Kind regards,
Arjan



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