[cdi-dev] Producer#dispose(T instance) and similar

Arne Limburg arne.limburg at openknowledge.de
Wed Dec 12 02:46:54 EST 2012


Hi Mark,
Hi Pete,

>From reading the spec literally I must admit that Pete seems to be right
and the returned object of a producer method is not a "bean" in the sense
of the spec. But then there are MANY parts of the spec where we MUST
clarify the usage of the term "bean", because they apply to the result of
a producer method, too. AND for a producer method there is a Bean<T>
object available (The ProcessBean event is fired, see 11.5.11) which is
confusing, if the returned object is not a "bean".

And my last point: The definition as Pete understands it, would result in
very unexpected behavior. Consider the following producer method:

@Produces
@MyStereotype
public MyObject produce() {
  ...
}


And the following stereotype:

@Stereotype
@RequestScoped
@CustomQualified
@CustomIntercepted
public @interface MyStereotype {}

where the @CustomQualified and @CustomIntercepted annotations are a
qualifier and an interceptor binding.
The resulting object would have @RequestScoped and @CustomQualified
applied, but not @CustomIntercepted... How would we explain that to our
users?
This behavior is not so clear in CDI 1.0, but would become clearer in CDI
1.1.
We should definitely change some clarifications in another direction.
Have not looked at Decorators and produced objects, but I guess there are
many things to be clarified, too…

Just my two cent,
Cheers,
Arne

Am 11.12.12 18:58 schrieb "Mark Struberg" unter <struberg at yahoo.de>:

>so a producer method in Weld does not result in a Bean<T> and is not
>being returned by BeanManager#getBeans() ?
>
>LieGrue,
>strub
>
>
>
>----- Original Message -----
>> From: Pete Muir <pmuir at redhat.com>
>> To: Mark Struberg <struberg at yahoo.de>
>> Cc: Arne Limburg <arne.limburg at openknowledge.de>; cdi-dev
>><cdi-dev at lists.jboss.org>
>> Sent: Tuesday, December 11, 2012 4:11 PM
>> Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>> 
>> Agreed, managed bean is a well defined term:
>> 
>> " 3.1. Managed beans
>> 
>> A managed bean is a bean that is implemented by a Java class."
>> 
>> So I'm pretty sure producers aren't managed beans.
>> 
>> 
>> On 11 Dec 2012, at 16:07, Mark Struberg wrote:
>> 
>>>  Actually I cannot read this restriction from the old wording. Please
>>>note 
>> that the terminus 'managed bean' is well defined and any producer
>>method 
>> is a 'managed bean' as well as explicitly defined in the spec. This is
>> not restricted to managed beans which are just classes imo.
>>> 
>>>  LieGrue,
>>>  strub
>>> 
>>> 
>>> 
>>>  ----- Original Message -----
>>>>  From: Pete Muir <pmuir at redhat.com>
>>>>  To: Mark Struberg <struberg at yahoo.de>
>>>>  Cc: Arne Limburg <arne.limburg at openknowledge.de>; cdi-dev
>> <cdi-dev at lists.jboss.org>
>>>>  Sent: Monday, December 10, 2012 1:37 PM
>>>>  Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>>>> 
>>>> 
>>>>  On 7 Dec 2012, at 22:06, Mark Struberg wrote:
>>>> 
>>>>>  Well, that restriction got only introduced with CDI-1.1.
>>>> 
>>>>  CDI 1.0 didn't require an impl to support this. To quote:
>>>> 
>>>>  "Interceptor bindings may be used to associate interceptors with
>> any 
>>>>  managed bean that is not itself an interceptor or decor- ator or
>>>>with 
>> any EJB 
>>>>  session or message-driven bean."
>>>> 
>>>>  "Decorators may be associated with any managed bean that is not
>> itself an 
>>>>  interceptor or decorator or with any EJB session bean."
>>>> 
>>>>  The restriction was just making it explicit, because people thought
>>>>it 
>> should 
>>>>  work.
>>>> 
>>>>> 
>>>>>  I've not noticed that, what was the reason? There is no
>> technical 
>>>>  necessity to do that imo!
>>>> 
>>>>  Maybe, but that isn't the way the spec is written in 1.0 :-) We can
>> change 
>>>>  it for sure, but it's a feature request.
>>>> 
>>>>> 
>>>>>  I can see that for
>>>>> 
>>>>> 
>>>>>  @Produces @Transactional User getUser() {..}
>>>>> 
>>>>> 
>>>>>  it is ambiguous whether the @Transactional interceptor should
>> account for 
>>>>  the method invocation or the produced bean.
>>>>>  But as Arne pointed out it is in CDI-1.0 very clear what should
>> happen with 
>>>> 
>>>>> 
>>>>>  @Produces @MyInterceptedStereotype User getUser() {}
>>>>> 
>>>>>  Should we reopen CDI-59?
>>>>> 
>>>>>  LieGrue,
>>>>>  strub
>>>>> 
>>>>> 
>>>>>  ----- Original Message -----
>>>>>>  From: Pete Muir <pmuir at redhat.com>
>>>>>>  To: Arne Limburg <arne.limburg at openknowledge.de>
>>>>>>  Cc: Mark Struberg <struberg at yahoo.de>; cdi-dev
>>>>  <cdi-dev at lists.jboss.org>
>>>>>>  Sent: Wednesday, December 5, 2012 4:55 PM
>>>>>>  Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>>>>>> 
>>>>>>  Hey Arne,
>>>>>> 
>>>>>>  No, they can't :-) It's specifically called out in
>> Chapter 8 
>>>>  and Chapter 
>>>>>>  9 that decorators and interceptors aren't applied to the
>> result of 
>>>>  producer 
>>>>>>  methods.
>>>>>> 
>>>>>>  Pete
>>>>>> 
>>>>>>  On 5 Dec 2012, at 14:47, Arne Limburg wrote:
>>>>>> 
>>>>>>>  Hi Pete,
>>>>>>> 
>>>>>>> 
>>>>>>>  A little of topic and I don't want to disturb your
>> discussion, 
>>>>  but:
>>>>>>> 
>>>>>>>  Beans produced by producer methods CAN have interceptors as
>> 
>>>>  stereotypes
>>>>>>>  are supported on producer methods.
>>>>>>> 
>>>>>>>  Cheers,
>>>>>>>  Arne
>>>>>>> 
>>>>>>>  Am 04.12.12 17:46 schrieb "Pete Muir" unter
>>>>>>  <pmuir at redhat.com>:
>>>>>>> 
>>>>>>>>  Hi Mark, I'll try to answer inline, but I'm
>> missing a 
>>>>  bit of 
>>>>>>  background
>>>>>>>>  about what you are doing...
>>>>>>>> 
>>>>>>>>  On 4 Dec 2012, at 14:20, Mark Struberg wrote:
>>>>>>>> 
>>>>>>>>>  Another problem probably being an interceptor on
>> the 
>>>>  @Disposes 
>>>>>>  method
>>>>>>>>>  itself.
>>>>>>>>>  Where does the Proucer#dispose(T instance) get the
>>>>  interceptor 
>>>>>>  from?
>>>>>>>>> 
>>>>>>>>>  LieGrue,
>>>>>>>>>  strub
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>  ----- Original Message -----
>>>>>>>>>>  From: Mark Struberg <struberg at yahoo.de>
>>>>>>>>>>  To: cdi-dev <cdi-dev at lists.jboss.org>
>>>>>>>>>>  Cc: 
>>>>>>>>>>  Sent: Tuesday, December 4, 2012 3:16 PM
>>>>>>>>>>  Subject: [cdi-dev] Producer#dispose(T instance)
>> and 
>>>>  similar
>>>>>>>>>> 
>>>>>>>>>>  Hi!
>>>>>>>>>> 
>>>>>>>>>>  I'm currently stumbling over implementing
>>>>>>>>>> 
>>>>>>>>>>  Producer#dispose(T instance) properly
>>>>>>>>>> 
>>>>>>>>>>  The Producer#produce(CreationalContext)
>>>>>>>>>> 
>>>>>>>>>>  has the CreationalContext parameter but the
>> dispose
>>>>>>>> 
>>>>>>>>  Right, it would have been good to have included it
>> here. 
>>>>  I'm not 
>>>>>>  sure why
>>>>>>>>  it wasn't, however I don't believe that it
>> causes a 
>>>>  problem 
>>>>>>  with the CDI
>>>>>>>>  1.0 spec, but just limits us going forward.
>>>>>>>> 
>>>>>>>>>>  and others do not have it.
>>>>>>>> 
>>>>>>>>  Yes.
>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  Problem here is that a Producer could probably
>> get 
>>>>  exchanged 
>>>>>>  via a
>>>>>>>>>>  portable
>>>>>>>>>>  extension via
>> ProcessProducer#setProducer(Producer)
>>>>>>>> 
>>>>>>>>  Yes, this is definitely supported
>>>>>>>> 
>>>>>>>>>>  so it could be from a
>>>>>>>>>>  foreign source which must not know anything
>> about 
>>>>  container
>>>>>>>>>>  implementation
>>>>>>>>>>  details.
>>>>>>>> 
>>>>>>>>  Yes.
>>>>>>>> 
>>>>>>>>  I think the critical part of the spec to understand
>> this is 
>>>>  11.2. 
>>>>>>  I'm
>>>>>>>>  quoting here from the CDI 1.1 spec, into which we have
>> add the
>>>>>>>>  clarification that "The instance returned by
>> produce() may 
>>>>  be a 
>>>>>>  proxy.".
>>>>>>>>  The part about building interceptors and decorators is
>> there in 
>>>>  CDI 
>>>>>>  1.0.
>>>>>>>> 
>>>>>>>>>  For a Producer that represents a class:
>>>>>>>>> 
>>>>>>>>>       € produce() calls the constructor annotated
>> @Inject if 
>>>>  it 
>>>>>>  exists, or
>>>>>>>>>  the constructor with no parameters otherwise, as
>> defined in
>>>>>>>>>  [instantiation], and returns the resulting
>> instance. If the
>>>>  class 
>>>>>>  has
>>>>>>>>>  interceptors,produce() is responsible for building
>> the 
>>>>  interceptors 
>>>>>>  and
>>>>>>>>>  decorators of the instance. The instance returned
>> by 
>>>>  produce() may
>>>>>>  be a
>>>>>>>>>  proxy.
>>>>>>>>> 
>>>>>>>>>       € dispose() does nothing.
>>>>>>>> 
>>>>>>>>  and
>>>>>>>> 
>>>>>>>>>  For a Producer that represents a producer method or
>> field:
>>>>>>>>> 
>>>>>>>>>       € produce() calls the producer method on, or
>> accesses 
>>>>  the 
>>>>>>  producer
>>>>>>>>>  field of, a contextual instance of the bean that
>> declares 
>>>>  the 
>>>>>>  producer
>>>>>>>>>  method, as defined in [methods].
>>>>>>>>> 
>>>>>>>>>       € dispose() calls the disposer method, if any,
>> on a 
>>>>  contextual
>>>>>>>>>  instance of the bean that declares the disposer
>> method, as 
>>>>  defined 
>>>>>>  in
>>>>>>>>>  [methods], or performs any additional required
>> cleanup, if 
>>>>  any, to
>>>>>>>>>  destroy state associated with a resource.
>>>>>>>> 
>>>>>>>>  Now, let me start to break down your sentence :-)
>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  What now about having an interceptor on
>> @PreDestroy?
>>>>>>>> 
>>>>>>>>  For a start, it's worth remembering interceptors
>> can only 
>>>>  be 
>>>>>>  associated
>>>>>>>>  with beans defined by a class. If the bean is a
>> producer, then 
>>>>  you 
>>>>>>  can't
>>>>>>>>  intercept the instance produced (only the invocation of
>> the 
>>>>  producer).
>>>>>>>> 
>>>>>>>>>>  This is what you get if
>>>>>>>>>>  your interceptor has a at PreDestroy method
>> himself as per 
>>>>  the
>>>>>>>>>>  interceptors and EJB
>>>>>>>>>>  specs. That would mean that the instance passed
>> to 
>>>>  dispose() 
>>>>>>  whould be
>>>>>>>>>>  the 
>>>>>>>>>>  proxy? That purely sounds wrong to me.
>>>>>>>> 
>>>>>>>>  Based on my comment from above, I think it's clear
>> that 
>>>>  dispose() 
>>>>>>  should
>>>>>>>>  never try to invoke predestroy methods. That is the job
>> of
>>>>>>>>  InjectionTarget.preDestroy(). I would expect a proxy to
>> be 
>>>>  passed to
>>>>>>>>  preDestroy().
>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  Another issue being
>> InjectionTarget#postConstruct()
>>>>  only having 
>>>>>>  the
>>>>>>>>>>  instance T
>>>>>>>>>>  as well. Now what about @PostConstruct
>> interceptors as 
>>>>  defined 
>>>>>>  in the
>>>>>>>>>>  interceptors spec?
>>>>>>>> 
>>>>>>>>  Again, I would expect a proxy to be passed to
>> postConstruct().
>>>>  Anyway,
>>>>>>>>  I'm not sure why you need access to the creational
>> context 
>>>>  in the
>>>>>>>>  postConstruct()? Here you should just invoke the
>> postConstruct 
>>>>>>  callback,
>>>>>>>>  which should create any new dependent objects.
>>>>>>>> 
>>>>>>>>>>  Currently we have a dirty hack in OWB to pass
>> over the
>>>>>>>>>>  CreationalContext which
>>>>>>>>>>  contains the dependent scoped interceptors for
>> our own 
>>>>>>  Producers and
>>>>>>>>>>  InjectionTargets. But I have no clue yet how
>> that 
>>>>  should get
>>>>>>>>>>  implemented if one
>>>>>>>>>>  plugs in a portable Producer via an Extension
>> ^^
>>>>>>>>>> 
>>>>>>>>>>  Who is responsible of performing the
>> interception? The
>>>>>>  Producer? Or
>>>>>>>>>>  must the
>>>>>>>>>>  instance being handed into already be a Proxy?
>>>>>>>> 
>>>>>>>>  The instance returned from produce() should have
>> interceptors 
>>>>  and
>>>>>>>>  decorators applied.
>>>>>>>> 
>>>>>>>>  Please let me know if above makes sense, it took me a
>> while to 
>>>>  work out
>>>>>>>>  whether what was defined was sane. After quite a lot of
>> 
>>>>  thinking +
>>>>>>>>  talking to Jozef and Stuart I came to the conclusion it
>> was, 
>>>>  but  if 
>>>>>>  you
>>>>>>>>  can poke holes then please do!
>>>>>>>>  _______________________________________________
>>>>>>>>  cdi-dev mailing list
>>>>>>>>  cdi-dev at lists.jboss.org
>>>>>>>>  https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>>>>> 
>>>>>> 
>>>> 
>> 




More information about the cdi-dev mailing list