[weld-dev] Not possible to destroy normal scoped beans returned by producer method

Martin Kouba mkouba at redhat.com
Thu Sep 15 08:09:40 EDT 2016


I see. Well, this is a bit problematic. The main problem is that Weld 
session context does not always synchronize with the underlying 
HttpSession. There is a thread local bean store which is 
"write-through", i.e. if attached any modifications are written to the 
HttpSession immediately. But in your case, the destroy operation is not 
recognized as a modification (bean instance is not found in the thread 
local bean store).

I think we can fix this particular problem - I've created WELD-2234 to 
track this issue.

I think this is undefined from spec point of view. And I'm not quite 
sure it would be possible to specify it in a clear way.

Martin

Dne 15.9.2016 v 11:58 arjan tijms napsal(a):
> Hi,
>
> Just a quick follow up, it seems that if the bean is touched in 1
> request (so it's actually constructed and in the "global" bean store for
> the session), then destroyed in another request within the same session
> that hasn't touched the bean it fails.
>
> But like you said, if the bean is touched within the same request (e.g.
> @Inject Foo foo; ... foo.toString();) then destroying it works.
>
> I'm not sure, do you think this is a bug, a spec issue, or "just the way
> things are"?
>
> Kind regards,
> Arjan Tijms
>
>
>
>
> On Thu, Sep 15, 2016 at 8:59 AM, arjan tijms <arjan.tijms at gmail.com
> <mailto:arjan.tijms at gmail.com>> wrote:
>
>     Hi,
>
>     The produced Foo should have been used before it's destroyed, but
>     I'll double check it's also used right before the destroy method is
>     called in the same thread. I'll try to make a simple reproducer as
>     well if it still doesn't work correctly then.
>
>     Kind regards,
>     Arjan Tijms
>
>     On Thu, Sep 15, 2016 at 8:48 AM, Martin Kouba <mkouba at redhat.com
>     <mailto:mkouba at redhat.com>> wrote:
>
>         Hi Arjan,
>
>         a simple reproducer would be helpful. There are few edge cases
>         around session context and HTTP session which are problematic
>         (e.g. HttpSession.invalidate()).
>
>         Do you call some method on the produced Foo before you call
>         destroy? Because in Weld, normal scoped instances are created
>         lazily and so does the HTTP session in case of @SessionScoped.
>
>         Thanks,
>
>         Martin
>
>         Dne 14.9.2016 v 19:14 arjan tijms napsal(a):
>
>             Hi,
>
>             I have a simple producer:
>
>             @Produced
>             @SessionScoped
>             public void Foo getFoo() { return new Foo());
>
>             If I subsequently want to destroy the Bean using:
>
>             Set<Bean<?>> beans = beanManager.getBeans(Foo.class);
>
>             Bean<?> bean = (Bean<T>) beanManager.resolve(beans);
>             Context context = beanManager.getContext(bean.ge
>             <http://bean.ge>tScope());
>
>             ((AlterableContext) context).destroy(bean);
>
>             Then in Weld 2.3.2 the destroy method of the super class
>             of org.jboss.weld.context.http.Ht
>             <http://org.jboss.weld.context.http.Ht>tpSessionContextImpl
>             is called:
>
>             org.jboss.weld.context.AbstractContext
>
>             Containing this code:
>
>                 @Override
>                 public void destroy(Contextual<?> contextual) {
>                     if (!isActive()) {
>                         throw new ContextNotActiveException();
>                     }
>                     checkContextInitialized();
>                     if (contextual == null) {
>                         throw ContextLogger.LOG.contextualIsNull();
>                     }
>                     final BeanStore beanStore = getBeanStore();
>                     if (beanStore == null) {
>                         throw ContextLogger.LOG.noBeanStoreAvailable(this);
>                     }
>                     BeanIdentifier id = getId(contextual);
>                     ContextualInstance<?> beanInstance =
>             beanStore.remove(id);
>                     if (beanInstance != null) {
>                         RequestScopedCache.invalidate();
>                         destroyContextualInstance(beanInstance);
>                     }
>                 }
>
>             Now the getBeanStore() method
>             (from org.jboss.weld.context.AbstractBoundContext) returns an
>             org.jboss.weld.context.beanstore.http.LazySessionBeanStore
>             and this bean
>             store does *not* contain the Foo bean (no key for its
>             BeanIdentifier).
>             There are other session scoped beans there that have been
>             instantiated
>             for the test, but Foo is missing.
>
>             If subsequently the session is destroyed, the same destroy
>             method is
>             called on the
>             org.jboss.weld.context.http.Ht
>             <http://org.jboss.weld.context.http.Ht>tpSessionContextImpl
>             eventually, but now
>             the getBeanStore() method returns
>             an
>             org.jboss.weld.context.beanstore.http.EagerSessionBeanStore,
>             and this
>             one *does* contain the Foo bean.
>
>             The other beans that the EagerSessionBeanStore contain are
>             equal to the
>             ones in the LazySessionBeanStore, the only difference is the
>             Foo bean.
>
>             Is this a bug in Weld or am I doing something wrong?
>
>             Kind regards,
>             Arjan Tijms
>
>
>
>
>
>
>
>
>
>
>
>             _______________________________________________
>             weld-dev mailing list
>             weld-dev at lists.jboss.org <mailto:weld-dev at lists.jboss.org>
>             https://lists.jboss.org/mailman/listinfo/weld-dev
>             <https://lists.jboss.org/mailman/listinfo/weld-dev>
>
>
>

-- 
Martin Kouba
Software Engineer
Red Hat, Czech Republic


More information about the weld-dev mailing list