On Wed, May 11, 2016 at 5:58 AM arjan tijms <arjan.tijms@gmail.com> wrote:
Hi,

On Wed, May 11, 2016 at 11:43 AM, Martin Kouba <mkouba@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@redhat.com
        <mailto:mkouba@redhat.com>
        <mailto:mkouba@redhat.com <mailto:mkouba@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@lists.jboss.org <mailto:cdi-dev@lists.jboss.org>
        <mailto:cdi-dev@lists.jboss.org <mailto:cdi-dev@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@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.