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

[jsr372-experts] Re: Should _at_SessionScoped Beans Allow Injection of Resources

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 10 Apr 2015 14:44:48 -0700

>>>>> On Sat, 4 Apr 2015 12:30:42 -0500, Josh Juneau <juneau001_at_gmail.com> said:

JJ> I am developing an example application to demonstrate the features of JSF
JJ> 2.3.

This is great news. In the past these applications have tended to
become quite famous. Starting with CarDemo, following up with
ScrumToys, and now your new app.

JJ> I've encountered what I would call an issue, a while back, as I was
JJ> unable to inject any of the Faces CDI resources into @SessionScoped
JJ> beans, unless I mark the injected resource(s) as transient. I have
JJ> no problems injecting them into @Dependent or @RequestScoped beans,
JJ> of course. This is obviously occurring because the producers are
JJ> not passivation capable.

>>>>> On Sat, 4 Apr 2015 20:40:35 +0200, arjan tijms <arjan.tijms_at_gmail.com> said:

AT> Indeed, I discussed this before with Manfred. It's technically as simple as
AT> letting the producer implement that interface. After that it works. Since
AT> the producer is request scoped CDI will create a proxy that always
AT> delegates to the right instance.

While it can be done, doing it seems a bit "magic" to me.

JJ> In my opinion, there are some cases where it makes sense to utilize a
JJ> @SessionScoped bean that contains injected resources...perhaps
JJ> @FacesContext, for issuing a FacesMessage. While we can certainly utilize
JJ> @RequestScoped beans that utilize @SessionScoped beans for management of
JJ> objects that need to stay within the session, that may be cumbersome under
JJ> some circumstances, and I can see the use case of allowing injection of
JJ> resources into @SessionScoped beans.

AT> They should be injectable in session scoped beans. From my part there is no
AT> doubt there ;)

This is a "correctness" issue. Semantically, I don't think it's
sensible to inject things that only have meaning in the scope of a jsf
request into something that lasts longer than that. However, the
ensuing discussion has lead me to think we can support this without
introducing confusion.

On the other hand, we have many years of precedent which states that you
should not place dependencies on "narrower" scoped things from "wider"
scoped things.

MS> I think a whole lot of things get mixed up here.

MS> a.) The interface doesnt matter at all. The only thing which counts
MS> is that the return type must not be a final non-serilizable class.

MS> b.) For producer methods creating any NormalScoped bean
MS> (e.g. @RequestScoped) you will ALWAYS get a Serializable proxy. No
MS> matter if the contextual instance is serializable or not.

MS> c.) For producer methods creating a @Dependent scoped bean it
MS> depends on the actual returned instance. If the instance returned at
MS> runtime is serializable then all is fine.

MS> All other behaviour is simply a bug in the implementation you did use.

Do you mean the fact that it works is a bug?

>>>>> On Sun, 5 Apr 2015 22:34:19 +0200, Mark Struberg <struberg_at_yahoo.de> said:

MS> I agree its not really clear in the spec. Actually I would suggest
MS> to make each and every Bean<T> impl implement PassivationCapable.

Yes, this is akin to always adding a SerialVersionUID.

>>>>> On Sun, 5 Apr 2015 22:31:30 +0200, Mark Struberg <struberg_at_yahoo.de> said:

MS> Yes, and that is simply a bug. There is nothing wrong with CDI in
MS> general, just a simple bug in Mojarra. Ed, feel free to ping me and
MS> Ill explain. Or we sit together over a coffee next week and I help
MS> you fixing this.

>>>>> On Mon, 6 Apr 2015 12:58:23 +0200, arjan tijms <arjan.tijms_at_gmail.com> said:

AT> It does, thanks a lot for the thorough explanation. I'll prepare a
AT> changebundle for Mojarra and/or discuss it with Manfred.

Yes please. We'll have to have the coffe over another issue. There are
many!

[...]

MS> But the next 2 are only indirectly defined

MS> 2.) Serialisation of the Contextual Reference. This is what blows up
MS> in your case. And it is independent on whether your own contextual
MS> instance gets serialized or not. Consider an @ApplicationScoped
MS> MyService which is not serializable. And now you inject this into a
MS> @SessionScoped MyView. When MyView gets serialized (cluster) then
MS> the proxy for MyService which got injected into MyView gets
MS> serialized as well. And this proxy (the Contextual Reference) just
MS> serializes the passivationId over to the other node. We cannot
MS> serialize the whole Bean<T> as it usually contains refs to a lot of
MS> Class<?>, Method<?>, Field<?> etc. On the other node this gets
MS> connected to the Bean<T> again via
MS> BeanManager#getPassivationCapableBean(String id)

Ahh, thanks. That explains it.

MS> 3.) Injecting a @Dependent bean into a passivating scoped
MS> bean. E.g. injecting an @Dependent MyStateHelper into a @ViewScoped
MS> JsfBackingBean. In that case the Bean<MyStateHelper> gets stored in
MS> the CreationalContext of your JsfBackingBean. And this gets
MS> serialized along to the Client or other node with the ViewContext

>>>>> On Mon, 6 Apr 2015 18:28:24 +0000 (UTC), Mark Struberg <struberg_at_yahoo.de> said:

MS> Agree, I prefer to strictly distinguish between the following 3
MS> different terms

MS> * Bean. For CDI always means Bean<T> in the sense of a factory rule

For me, always using the FQCN would be better:
javax.enterprise.inject.spi.Bean.

MS> * Contextual Instance: the one single 'singleton' per your scope context

MS> * Contextual Reference: the proxy for your Contextual Instance. This
MS> is what you get injected and what you get via
MS> BeanManager#getReference().

These are two great terms.

Ed

-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
|  1 days til CONFESS 2015