[cdi-dev] Destroying @Stateless proxies obtained via CDI.current().select()

Martin Kouba mkouba at redhat.com
Wed May 11 05:43:36 EDT 2016


Dne 11.5.2016 v 11:20 arjan tijms napsal(a):
> Hi,
>
> On Wed, May 11, 2016 at 10:54 AM, Martin Kouba <mkouba at redhat.com
> <mailto:mkouba at redhat.com>> wrote:
>
>     Hi Arjan,
>
>     the test attached to WELD-2148 is wrong. We can not inspect an
>     actual SLSB instance. The only thing we could test is that
>     Instance.destroy() does not throw UnsupportedException for SLSB CDI
>     reference.
>
>
> I see, thanks for the clarification!
>
> Going forward, would it not be convenient if an Instance
> was AutoCloseable, so that one could do:

I don't think so. Remember that Instace is more like a "factory" and not 
only for @Dependent objects. What would actually close() do? 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


More information about the cdi-dev mailing list