[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