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
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