[cdi-dev] Destroying @Stateless proxies obtained via CDI.current().select()
John D. Ament
john.d.ament at gmail.com
Wed May 11 06:16:24 EDT 2016
On Wed, May 11, 2016 at 5:58 AM arjan tijms <arjan.tijms at gmail.com> wrote:
> Hi,
>
> On Wed, May 11, 2016 at 11:43 AM, Martin Kouba <mkouba at redhat.com> wrote:
>
>> I don't think so. Remember that Instace is more like a "factory" and not
>> only for @Dependent objects. What would actually close() do?
>
>
> I'd intuitively say release and where appropriate destroy all beans that
> were created from that particular instance of uhm Instance. But maybe the
> existing semantics of Instance aren't a good fit for that.
>
> Thinking out loud, maybe an AutoInstance variant?
>
> try (AutoInstance<Foo> fooInstance = CDI.current().autoSelect(Foo.class)) {
>
> Foo foo = fooInstance.get();
> foo.bar();
> }
>
>
Sounds very similar to my original proposal, I would just use dependent in
this case, unless we want to hide that from the developer.
> autoSelect could even throw early if the selected bean is not dependent
> scoped. But as mentioned, just thinking out loud here.
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>> Also the users would be tempted to use this for injected Instance which
>> does not make sense.
>>
>>
>>> try (Instance<Foo> fooInstance =CDI.current().select(Foo.class)) {
>>>
>>> Foo foo = fooInstance.get();
>>> foo.bar();
>>> }
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>> Martin
>>>
>>> Dne 11.5.2016 v 10:40 arjan tijms napsal(a):
>>>
>>> Hi Martin,
>>>
>>> Thanks for the swift action and the reference. I do have one more
>>> question looking at the test that was added. It now uses this
>>> SLSB:
>>>
>>> @Stateless
>>> public class SLSessionBean {
>>>
>>> public void ping(){
>>> }
>>>
>>> static final AtomicBoolean DESTROYED = new AtomicBoolean();
>>>
>>> @PreDestroy
>>> public void destroy() {
>>> DESTROYED.set(true);
>>> }
>>> }
>>>
>>> The assertion in the test is that the (a?) SLSB is actually
>>> destroyed,
>>> but wasn't the idea that only the internal reference is
>>> destroyed, and
>>> the bean just stays in the pool?
>>>
>>> Here it looks like the code intends to destroy a random SLSB
>>> instance
>>> from the pool. (random, since I guess an internal reference
>>> doesn't
>>> stick to the same actual instance of a SLSB, otherwise you would
>>> get
>>> stateful like semantics).
>>>
>>> Or did I miss something?
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>> On Wed, May 11, 2016 at 9:11 AM, Martin Kouba <mkouba at redhat.com
>>> <mailto:mkouba at redhat.com>
>>> <mailto:mkouba at redhat.com <mailto:mkouba at redhat.com>>> wrote:
>>>
>>> Hi Arjan,
>>>
>>> I believe it's a Weld bug - you should be able to use
>>> Instance.destroy() to discard an internal SLSB proxy. See
>>> also
>>> "Lifecycle of stateless and singleton session beans" [1].
>>> Tomas
>>> Remes created WELD-2148 to track this issue [2].
>>>
>>> Also the "leak" is an expected behaviour. See for example
>>> WELD-920
>>> [3] discussion.
>>>
>>> Martin
>>>
>>> [1]
>>>
>>> http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#stateless_lifecycle
>>>
>>> [2]
>>> https://issues.jboss.org/browse/WELD-2148
>>>
>>> [3]
>>> https://issues.jboss.org/browse/WELD-920
>>>
>>> Dne 10.5.2016 v 17:11 arjan tijms napsal(a):
>>>
>>> Hi,
>>>
>>> Given a simple @Stateless bean:
>>>
>>> @Stateless
>>> public class Foo {
>>> public void bar() {}
>>> }
>>>
>>> Then requesting an instance of this via CDI as follows:
>>>
>>> Foo foo = CDI.current().select(Foo.class).get();
>>>
>>> Causes a lot of leaked proxy instances (at least on
>>> Weld). Now
>>> what I
>>> guess needs to be done is destroying the proxy, taking
>>> Antoine's
>>> answer
>>> here as a lead:
>>>
>>> http://stackoverflow.com/questions/28767536/scope-of-stateless-bean
>>>
>>> Only the following throws an
>>> UnsupportedOperationException (on Weld
>>> 2.3.2, haven't tested OWB yet)
>>>
>>> Instance<Foo> fooInstance
>>> =CDI.current().select(Foo.class);
>>> Foo foo = fooInstance.get();
>>> foo.bar();
>>> fooInstance.destroy(foo);
>>>
>>> The question is, is this how it's supposed to be done
>>> via the spec?
>>>
>>> Implementation wise, what happens in Weld is that the
>>> CDI/EJB proxy
>>> (com.test.Foo$Proxy$_$$_Weld$EnterpriseProxy$) in the
>>> following code
>>> doesn't hit the check for a dependent instance
>>> (comments in capitals
>>> added by me):
>>>
>>>
>>> public void destroy(T instance) {
>>> Preconditions.checkNotNull(instance);
>>>
>>> // check if this is a proxy of a
>>> normal-scoped bean
>>> if (instance instanceof ProxyObject) {
>>>
>>> // THIS BRANCH IS TAKEN FOR CDI/EJB PROXY
>>>
>>> ProxyObject proxy = (ProxyObject)
>>> instance;
>>> if (proxy.getHandler() instanceof
>>> ProxyMethodHandler) {
>>> ProxyMethodHandler handler =
>>> (ProxyMethodHandler)
>>> proxy.getHandler();
>>> Bean<?> bean = handler.getBean();
>>> Context context =
>>> getBeanManager().getContext(bean.getScope());
>>> if (context instanceof
>>> AlterableContext) {
>>> AlterableContext alterableContext
>>> =
>>> (AlterableContext) context;
>>>
>>> // CONTEXT IS A
>>> DEPENDENTCONTEXTIMPL THAT
>>> THROWS
>>> // UnsupportedOperationException
>>> FROM ITS
>>> DESTROY()
>>> METHOD
>>> alterableContext.destroy(bean);
>>> return;
>>> } else {
>>> throw
>>> BeanLogger.LOG.destroyUnsupported(context);
>>> }
>>> }
>>> }
>>>
>>> // check if this is a dependent instance
>>> CreationalContext<? super T> ctx =
>>> getCreationalContext();
>>> if (ctx instanceof WeldCreationalContext<?>) {
>>> WeldCreationalContext<? super T> weldCtx
>>> = cast(ctx);
>>>
>>> // PROXY REFERENCES ARE KEPT HERE IN A
>>> // "dependentInstances" LIST, AND WOULD
>>> BE CLEARED
>>> HERE
>>> // BUT THIS CODE IS NEVER REACHED
>>>
>>> weldCtx.destroyDependentInstance(instance);
>>> }
>>> }
>>>
>>> Now I wonder, am I doing something wrong (according to
>>> the CDI
>>> spec), or
>>> could this be a bug in the Weld code?
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
>>> <mailto:cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org
>>> >>
>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>
>>> Note that for all code provided on this list, the
>>> provider
>>> licenses the code under the Apache License, Version 2
>>> (http://www.apache.org/licenses/LICENSE-2.0.html). For
>>> all other
>>> ideas provided on this list, the provider waives all
>>> patent and
>>> other intellectual property rights inherent in such
>>> information.
>>>
>>>
>>> --
>>> Martin Kouba
>>> Software Engineer
>>> Red Hat, Czech Republic
>>>
>>>
>>>
>>> --
>>> Martin Kouba
>>> Software Engineer
>>> Red Hat, Czech Republic
>>>
>>>
>>>
>> --
>> Martin Kouba
>> Software Engineer
>> Red Hat, Czech Republic
>>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the
> code under the Apache License, Version 2 (
> http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
> provided on this list, the provider waives all patent and other
> intellectual property rights inherent in such information.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/cdi-dev/attachments/20160511/d594c1aa/attachment-0001.html
More information about the cdi-dev
mailing list