[cdi-dev] Destroying beans from an interceptor
Jozef Hartinger
jharting at redhat.com
Fri Nov 14 04:49:05 EST 2014
On 11/13/2014 04:27 PM, arjan tijms wrote:
> Hi,
>
> On Wednesday, November 12, 2014, Jozef Hartinger <jharting at redhat.com
> <mailto:jharting at redhat.com>> wrote:
>
> Hi Arjan,
>
> there is a bug in Weld (WELD-1785) preventing this from working
> which is going to be fixed in the next release. What you are doing
> should work IMO as long as the interceptor does not call any other
> methods on the target instance.
>
>
> That's great to hear really.
>
> I'm slightly confused through why Mark thinks this cannot really work,
> while you say it should.
Don't be confused by that. This often happens to me and Mark :-)
>
> Is there something in the spec that may need to be clarified here? Ie
> some words about what an interceptor is at least allowed to do and
> what is definitely not allowed?
>
> In addition it must count with the target instance being destroyed
> within the instance.destroy() call.
>
>
> Sorry, I don't fully follow this. You mean something must be counted?
I mean that the interceptor (and others in the chain) should be tolerant
and not be surprised finding itself and the target bean destroyed
immediately after the instance.destroy() call.
>
>
> Perhaps a nicer way of doing this would be:
>
> @Inject
> @Intercepted
> private Bean<?> bean;
>
> Context context = manager.getContext(bean.getScope());
> if (!(context instanceof AlterableContext)) {
> throw new IllegalStateException("Context does not
> support removal of instances");
> }
> AlterableContext alterableContext =
> AlterableContext.class.cast(context);
> alterableContext.destroy(bean);
>
>
> I tried something close to that as well, just used the bean manager to
> resolve a Bean from the target object. Thanks for the suggestion!
>
> Kind regards,
> Arjan
>
>
> On 11/10/2014 02:59 PM, arjan tijms wrote:
>
> Hi,
>
> I wonder if it would be allowed according to the CDI spec to
> destroy a
> bean instance from within an interceptor.
>
> To test this (on Weld) I used the following code:
>
> @Interceptor
> @DestroyOnError
> @Priority(APPLICATION)
> public class DestroyOnErrorInterceptor implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> @AroundInvoke
> public Object tryInvoke(InvocationContext ctx) throws
> Exception {
>
> try {
> return ctx.proceed();
> } catch (Exception e) {
> destroy(ctx.getMethod().getDeclaringClass());
> throw e;
> }
> }
>
> private <T> void destroy(Class<T> clazz) {
> Instance<T> instance = CDI.current().select(clazz);
> instance.destroy(instance.get());
> }
>
> }
>
>
> When I use this interceptor on a SessionScoped bean:
>
> @SessionScoped
> public class TestBean implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> @DestroyOnError
> public void test() {
> throw new IllegalStateException();
> }
> }
>
> And then inject said bean in say a Servlet and call the test()
> method,
> destruction of the bean happens partially, but as soon as Weld
> tried
> to invocate a preDestroy method, it goes through the bean
> proxy again,
> detects that "the" interceptor handler is already active, promptly
> skips its attempt to call a preDestroy method and then to add
> insult
> to injury tries to call a "proceed" method which is always
> null and
> thus throws a NPE.
>
> (this happens in
> org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke)
>
> I tried some alternative methods to destroy the bean such as:
>
>
> Bean<T> bean = resolve(beanManager, beanClass);
>
> AlterableContext context = (AlterableContext)
> beanManager.getContext(bean.getScope());
> context.destroy(bean);
>
> with resolve being:
>
> public static <T> Bean<T> resolve(BeanManager beanManager,
> Class<T> beanClass) {
> Set<Bean<?>> beans = beanManager.getBeans(beanClass);
>
> for (Bean<?> bean : beans) {
> if (bean.getBeanClass() == beanClass) {
> return (Bean<T>)
> beanManager.resolve(Collections.<Bean<?>>singleton(bean));
> }
> }
>
> return (Bean<T>) beanManager.resolve(beans);
> }
>
> But this resulted in the same problem.
>
> Any idea?
>
> Kind regards,
> Arjan Tijms
> _______________________________________________
> 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/20141114/3ad08a78/attachment-0001.html
More information about the cdi-dev
mailing list