-
1. Re: Weld : How to make injected objects with Instance<> being garbage-collected
jharting Nov 19, 2013 2:49 AM (in response to rde_perigee)You can call Instance.destroy() but this method is only available since CDI 1.1 (Weld 2.0)
-
2. Re: Weld : How to make injected objects with Instance<> being garbage-collected
mkouba Nov 19, 2013 4:30 AM (in response to rde_perigee)Or (if possible) change the scope of B to some normal scope. Notice that this behaviour is per the spec (see http://docs.jboss.org/cdi/spec/1.1/cdi-spec.html#dependent_objects and https://issues.jboss.org/browse/WELD-920 for some more information).
-
3. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Nov 20, 2013 3:11 AM (in response to mkouba)@Martin :
My B instances have default scope, so it won't work for me.
@Jozef :
I'm currently trying to migrate to CDI 1.1 (Weld 2.1.0.Final)
-
4. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Nov 20, 2013 4:15 AM (in response to rde_perigee)Reading weld documentation, I changed my mind. It seems the scopes could be what I was looking for. I need to dig this idea to confirm it can be useful in my case.
If it does not work, then I'll migrate to CDI 1.1.
-
5. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Nov 20, 2013 5:33 AM (in response to rde_perigee)Ok, what I was looking for is something like @ConversationScoped. But I'm in a Java SE application, so I have no access to context the @ConversationScoped needs : When calling Conversation#begin(), I get :
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped
It looks like this scope must be used in a JSF context.
Is there any mean for me to use this scope in any other way ?
-
6. Re: Weld : How to make injected objects with Instance<> being garbage-collected
mkouba Nov 20, 2013 8:07 AM (in response to rde_perigee)Yep, the conversation scope is only active during Servlet (CDI 1.1) and JSF (CDI 1.0) requests. You can't use it in Java SE easily.
-
7. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Dec 4, 2013 10:55 AM (in response to mkouba)I've changed my mind. I'm pretty sure implementing a custom scope here is exactly what fits to my situation. That's what I have begun to do.
I have my own scope and my own Context. Just have to activate it at the right place. That's what is blocking me right now :
@MyScope
class B{}
class MyContext extends AbstractBoundContext<Map<String, Object>>{
private static final DEWeldContext instance = new DEWeldContext();
public static DEWeldContext getInstance() {
return instance;
}
...
}
class A {
@Inject
private Instance<B> instanceB;
public B doSomethingWithContext(){
// Activate weld
final WeldContainer weld = new Weld().initialize();
((BeanManagerImpl) weld.getBeanManager()).addContext(MyContext.getInstance());
// Activate context
Map<String, Object> beanStore = new LinkedHashMap<String, Object>();
MyContext.getInstance().associate(beanStore);
MyContext.getInstance().activate();
B b = instanceB.get();
doSomethingElseInScopeOfMyContext();
// Here, MyContext.getInstance().getBeanStore() is empty ! b is in @Dependent scope context.
MyContext.getInstance().invalidate();
MyContext.getInstance().deactivate();
MyContext.getInstance().dissociate(beanStore);
}
Reading my code, do you see something I may do wrong ? The question is : Why is b handled by @Dependent scope context, instead of @MyScope scope context ?
-
8. Re: Weld : How to make injected objects with Instance<> being garbage-collected
mkouba Dec 5, 2013 7:22 AM (in response to rde_perigee)You have to register your context properly. "((BeanManagerImpl) weld.getBeanManager()).addContext(MyContext.getInstance())" is not a good way to go.
Briefly: create a portable extension (see the Weld reference guide) and add AfterBeanDiscovery observer (see also http://docs.jboss.org/cdi/spec/1.1/cdi-spec.html#abd).
-
9. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Dec 5, 2013 10:43 AM (in response to mkouba)I followed your suggestion :
public class MyExtension implements Extension {
public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
abd.addContext(MyContext.getInstance());
logger.log("Added MyContext")
}
}
and created a file in my resources referencing this extension, as described in the documentation (src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension) containing the fully qualified name of my extension.
At the application starting, I can see the log message I put in the afterBeanDiscovery.
But my b is still handled by @Dependent scope...
Do you have another idea ?
Edit : I have a @New annotation on my instanceB. Could it be responsible for such a problem ?
-
10. Re: Weld : How to make injected objects with Instance<> being garbage-collected
rde_perigee Dec 6, 2013 3:02 AM (in response to rde_perigee)Reading the documentation, I realized @New annotation only injects dependent beans. That' s why my scope never holds reference to injectd beans.
I have seen I made a mistake on understanding the purpose of Instance<>. I thought it could be used as "producer" fields (i.e. could inject a new object at each call to get()). But it is not the case. However, that's what I'm trying to do. I need class attributes able to inject new beans at each call, and these beans should be in the scope I defined.
-
11. Re: Weld : How to make injected objects with Instance<> being garbage-collected
mkouba Dec 6, 2013 3:47 AM (in response to rde_perigee)Well, built-in Instance bean is only used to programatically lookup bean instances (an alternative to @Inject) and new bean instance is not created if not necessary. On the other hand producer (field, method) is a type of a bean - defines how the bean instance is created, and can be bound to any scope.
Speaking of your requirement and built-in scopes - only @Dependent beans can be used to produce a new bean instance for each Instance.get(). Other scopes are normal and so there may be only one bean instance per bean per thread (see also 6.3 Normal scopes and pseudo-scopes). Also note that for normal scoped bean a proxy is always created.
You can also make @MyScope a pseudo-scope and return a new instance each time Context.get() is invoked.