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

Jozef Hartinger jharting at redhat.com
Mon Dec 10 05:00:05 EST 2012


On 12/10/2012 10:33 AM, Mark Struberg wrote:
>> My understanding of the spec is that an InjectionTarget is completely
>> responsible for building and invoking interceptors and decorators.
> That only got added in CDI-1.0. In CDI-1.0 it was _not_ defined.
Right, I am not saying this is crystal clear in the spec. This is how I 
understand the spec. The spec only says: " If the class has 
interceptors, produce() is responsible for building the interceptors and 
decorators of the instance"
>
> My point is that this is technically not possible for a _portable_ Producer and InjectionTarget to get it right!
>
> It would need to know exactly:
> * how the proxies work, ASF, Javassist, BCEL, etc
> * how to store the Interceptors and Decorators in the CreationalContext
> * how to _retrieve_ the Interceptors and Decorators our of the CreationalContext again!
Right, an extension can either wrap an existing producer that handles 
interceptors/decorators or provide its own InjectionTarget. The latter 
option makes sense in situations where the extension knows that the 
produced instance does not support interception/decoration. Otherwise it 
is more convenient to use the former option IMHO.
>
> I don't think this can be done in a portable way. At least I found no solution so far...
> An easy example: The produce(CC) method only has a CreationalContext parameter but not a BeanManager! So how would you e.g. resolve an @ApplicationScoped bean which contains the producer method?
The extension that wraps/creates the InjectionTarget instance can have 
the BeanManager injected. I am used to passing the BeanManager reference 
to the InjectionTarget during creation of the InjectionTarget instance 
and keeping it within the instance.
>
>
> The only solution I can think about is to define that setProducer and setInjectionTarget must only be used to _wrap_ the existing ones.
>
>
> LieGrue,
> strub
>
>
>
>
> ----- Original Message -----
>> From: Jozef Hartinger <jharting at redhat.com>
>> To: Mark Struberg <struberg at yahoo.de>
>> Cc: Pete Muir <pmuir at redhat.com>; cdi-dev <cdi-dev at lists.jboss.org>
>> Sent: Monday, December 10, 2012 10:23 AM
>> Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>>
>> My understanding of the spec is that an InjectionTarget is completely
>> responsible for building and invoking interceptors and decorators. The
>> produce() method can either return the target object (assuming there are
>> no interceptors or decorators) or a proxy that handles interception.
>> This is completely transparent to the container.
>>
>> The instance that the container retrieves from the produce() method is
>> then passed to postConstruct(), preDestroy() and dispose() methods. Note
>> that if the instance is a proxy it is a client proxy (creating client
>> proxies is the container's job, not InjectionTarget's) but rather an
>> interceptor/decorator enabling proxy which carries interceptor/decorator
>> instances. Therefore, the CreationalContext is not necessary in those
>> methods as the instance itself knows how to invoke interceptors/decorators.
>>
>> HTH,
>>
>> JH
>>
>> On 12/07/2012 10:56 PM, Mark Struberg wrote:
>>>>   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.
>>>   I think that would end up being highly non-portable and we must revert this
>> 'clarification' as it breaks a lot of stuff!
>>>   Proxies are the core business of the cdi container! If we allow/force a
>> pluggable Producer<T> to handle the interception proxying then this would
>> not be possible without knowing implementation details of the respective
>> container. This starts with the fact that we need to store the implicitly
>> @Dependent scoped Interceptors and Decorators in our CreationalContexts but we
>> do _not_ define an API to portably extract Interceptors and Decorators from them
>> later.
>>>
>>>   Also this contradicts the need that some functionality like e.g. CDI events
>> might be private methods. There is just no way to invoke a private method on a
>> proxy whose internal structure you don't know. And doing the interceptors
>> via subclassing instead of proxies would break both the EJB and the interceptors
>> spec which define that only 'external' calls must get intercepted.
>>>   LieGrue,
>>>   strub
>>>
>>>
>>>
>>>   ----- Original Message -----
>>>>   From: Pete Muir <pmuir at redhat.com>
>>>>   To: Mark Struberg <struberg at yahoo.de>
>>>>   Cc: cdi-dev <cdi-dev at lists.jboss.org>
>>>>   Sent: Tuesday, December 4, 2012 5:46 PM
>>>>   Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>>>>
>>>>   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