Thanks Mark, see some follow-up questions inlined below Regards LF
On Mon, Mar 9, 2015 at 9:46 AM, Mark Struberg <[email protected]> wrote: > > You can inject any additional bean to any container invoked method. E.g. > > public MyClass { > public void observer(@Observes MyEvent me, SomeOtherBean sob, > AndOneMoreBean omb) { > } > > This is basically the same for producer methods, observer methods, @Inject > constructors and @Inject methods. > > Let’s assume SomeOtherBean and AndOneMoreBean are @Dependent. > > Now there is a HUGE difference if your code looks either > > case A.) > > public class MyClass { > public void observer(@Observes MyEvent me, SomeOtherBean sob, > AndOneMoreBean omb) { > sob.doSomething(); > omb.logMe(); > } > } > > In this case it would be a mem leak if we would keep the CreationalContext > for sob and omb. This seems to be exactly your case, right? > > > case B.) > > public class MyClass { > private SomeOtherBean sob; > private AndOneMoreBean omb; > > public void observer(@Observes MyEvent me, SomeOtherBean sob, > AndOneMoreBean omb) { > this.sob = sob; > this.omb = omb; > } > } > > > In this case we NEED to keep the CreationalContext to be able to properly > clean it up. > Maybe the observer sample is not that obvious, but it really gets clear if > we look at @Inject methods > > Consider an EntityManagerFactory producer with @Dependent scope and the > following: > > I thought the case below would be able to dereference the EMF when the RequestScoped bean gets destroyed and after any @Dispose method has been called? Is that not the case? What I'm after is some kind of rule to rely on (and to spread in the project), e.g. do not use Instance|Provider<....> of a @Dependent bean when injecting into an @ApplicationScoped or @Singleton EJB.... Will I be safe if I do the following?: - Not use @Inject methods and @Inject constructors with @Dependent beans - Not use Instance|Provider<...> with @Dependent beans injected into @ApplicationScoped and @Singleton beans Then what about the following cases: - I use a @Dependent bean in a static factory method? - I use a @Dependent bean in factory method belonging to a class that is @ApplicationScoped > @RequestScoped > public class MyClass { > > private EntityManagerFactory emf; > > @Inject > private initEmf(EntityManagerFactory emf) { > this.emf = emf; > } > > In this very case we again NEED to store the CreateionalContext for the > EMF in our internal ‚parent‘ CreationalContext. Otherwise we have no way to > call the @Disposes method for the EMF if MyClass instance gets destroyed, > right? > That would soon create a pile of not-closed EMFs… ;) > > Otoh we have the following class > > > @RequestScoped > public class MyClass { > > private EntityManager em; > > @Inject > private initEm(EntityManagerFactory emf) { > this.em = emf.createEntityManager(); > } > > So we do NOT store the EntityManagerFactory but just call a method on it. > And then we do not need it anymore. Thus the emf must get destroyed > IMMEDIATELY after initEm() has finished. > In CDI-1.1 I introduced an own annotation for it: > javax.enterprise.inject.TransientReference > > In CDI-1.1 (OpenWebBeans-1.5.0 that is) you would write > > @Inject > private initEm(@TransientReference EntityManagerFactory emf) { > this.em = emf.createEntityManager(); > } > > Is @TransientReference and the functionality it adds the same as using Instance<...> and destroy(...) in CDI 1.1? > In CDI-1.0 projects I suggest you use the DeltaSpike > BeanProvider.getDependent(beanManager, EntityManagerFactory.class); which > has an explicit get() and destroy() method. Something CDI only added > afterwards. > > Clearer now? > Please ping back if there is still something missing. This is not really > an easy topic ;) > > LieGrue, > strub > > > > > > Am 04.03.2015 um 07:55 schrieb Lars-Fredrik Smedberg <[email protected] > >: > > > > @Mark @Romain could anyone of you explain this that was in a previous > message from Mark: > > > > "...The very same problem appears if you e.g. inject a @Dependent bean > into a producer method or @Inject method. This case is only fixed in the > CDI-1.1 spec by marking the injection point as @TransientReference..." > > > > I'm interested in understanding if this happens only if the producer > class or class containing the @Inject method/constructor is > @ApplicationScoped (that is if its the same case we discussed or something > else)? > > > > Also what about injecting @Dependent beans into a static producer method? > > > > Regards > > Fredrik > > > > On Mar 2, 2015 9:57 AM, "Lars-Fredrik Smedberg" <[email protected]> > wrote: > > @Mark > > > > Some questions > > > > 1. Is the problem with produces/@Inject method you talk about only a > problem if the producer methods class is @ApplicationScoped? Can you show > by example and maybe how to work around it? > > 2. When you say not care about Provider I guess I can still use > Instance<...> and call get and get it working? > > 3. So exactly what happens (when is the produced Child destroyed? Are > any @Observes @Destroyed caled?) if I do the following: > > > > @ApplicationScoped > > public Mother { > > > > @Inject @TransientReference @Instance<Child> children; //Assuming > @Inject @TransientReference @Provider<Child> will not work?? > > > > public void doSomething() { > > Child child = children.get(); //assuming one implementation only > > child.doSomething(); > > } > > } > > > > > > > > On Mon, Mar 2, 2015 at 9:11 AM, Mark Struberg <[email protected]> wrote: > > Hi! > > > > As Romain already explained there was only the chance to not cleanup > dependent beans properly (which might create a mem leak), or to collect > them to be able to release them laster. Which in case of @ApplicationScoped > parent means another mem leak. The very same problem appears if you e.g. > inject a @Dependent bean into a producer method or @Inject method. This > case is only fixed in the CDI-1.1 spec by marking the injection point as > @TransientReference. I would need to dig the spec if we only let this apply > to Instance<T>. And we do not really care about Provider<T> at all in CDI, > except that Instance<T> extends Provider<T>. > > > > An easy solution would be to simply use DeltaSpike > BeanProvider#getDependent. That way you can also properly destroy the bean > _inside_ your loop already. > > > > LieGrue, > > strub > > > > > > > > > > > Am 01.03.2015 um 18:02 schrieb Romain Manni-Bucau < > [email protected]>: > > > > > > https://issues.apache.org/jira/browse/OWB-1032 > > > > > > impl should be quite easy if you want to give it a try > > > > > > > > > Romain Manni-Bucau > > > @rmannibucau | Blog | Github | LinkedIn | Tomitriber > > > > > > 2015-03-01 17:58 GMT+01:00 Lars-Fredrik Smedberg <[email protected]>: > > > @Romain could u send the link to the jira (s)? Thanks > > > > > > On Mar 1, 2015 5:34 PM, "Lars-Fredrik Smedberg" <[email protected]> > wrote: > > > @Romain Yes... we use Provider when we know there is one > implementation and we like to lazy initialize a dep bean inside an > application scoped bean method.... guess we could use Instance and destroy > until it gets fixed in owb. . > > > > > > We have cases for instance where thr factory that injects instance is > application scoped but in that case the bean implementations are scoped and > not dependent. > > > > > > On Mar 1, 2015 5:13 PM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > Yes and no. In owb it does ATM - opened a jira linked to it - but > actually provider can be a single instance with lazy eval where Instance is > by design multiple instances. > > > Le 1 mars 2015 16:32, "Lars-Fredrik Smedberg" <[email protected]> a > écrit : > > > Shouldn't Provider faces the same issue as Instance? > > > > > > On Mar 1, 2015 10:44 AM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > Owb 1.5 > > > > > > I dont think it is in provider api > > > > > > Le 1 mars 2015 03:13, "Lars-Fredrik Smedberg" <[email protected]> a > écrit : > > > @Romain btw destroy should work on Provider also right? > > > > > > On Mar 1, 2015 2:56 AM, "Lars-Fredrik Smedberg" <[email protected]> > wrote: > > > Thanks Romain for the explanation... I guess this will solve alot of > the use-cases / cases we talked about. > > > > > > Do you know what version of OWB this is implemented in? > > > > > > On Feb 28, 2015 10:08 PM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > Well issue before was release was not bound to the created instance > but znclosing class. Cdi 1.1 fixed it and now created instances can have > their own lifecycle and be handled by themselves. A bit like what Unmanaged > allows. > > > > > > @Inject Instance<A> a; > > > > > > A inst = a.get(); > > > a.destroy(inst); > > > > > > Le 28 févr. 2015 17:56, "Lars-Fredrik Smedberg" <[email protected]> > a écrit : > > > @Romain maybe I'm slow today (i am on vacation :-)) do u mind explain > with an example? > > > > > > On Feb 28, 2015 5:44 PM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > It call release on the instance creational context and each instance > has a child creational context of the parent. Said otherwise it is as if > the bean as a scope handled manually > > > > > > Le 28 févr. 2015 17:32, "Lars-Fredrik Smedberg" <[email protected]> > a écrit : > > > @Romain > > > > > > Can explain to me what difference it will make (what the fix does) > > > > > > On Feb 28, 2015 3:49 PM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > PS: to be complete CDI 1.x, x > 0 added destroy(X) in Instance API to > fix it > > > > > > > > > Romain Manni-Bucau > > > @rmannibucau | Blog | Github | LinkedIn | Tomitriber > > > > > > 2015-02-28 11:20 GMT+01:00 Karl Kildén <[email protected]>: > > > Got it, thanks all! > > > > > > On 27 February 2015 at 19:54, John D. Ament <[email protected]> > wrote: > > > It's a good approach, I do something similar at times. However, you > need to make sure the beans have scopes to avoid this memory leak. > > > > > > > > > On Fri, Feb 27, 2015 at 1:47 PM Karl Kildén <[email protected]> > wrote: > > > Hrmm not sure what you mean. This is not a framework it is business > logic and I really like to put validators in a list like this instead of if > else if else if else if > > > > > > On 27 February 2015 at 19:37, Romain Manni-Bucau < > [email protected]> wrote: > > > Mark will surely say you that configuring anyThingCriterion will make > your iterable size (if i can say it) = 1 even if you have 100 criterions ;) > > > > > > this is not a real spi > > > > > > > > > Romain Manni-Bucau > > > @rmannibucau | Blog | Github | LinkedIn > > > > > > 2015-02-27 19:34 GMT+01:00 Karl Kildén <[email protected]>: > > > Hi John! > > > > > > Summary: we use it as iterable > > > > > > Long story for completeness: > > > > > > Basically we get a thing from our business partner (inputThing) and > map it to our representation of thing (ProcessedThing) > > > > > > Each ThingCriterion can veto the processedThing and then they used > inputThing to print a pretty error message. When the Thing is enhanced > (happens all the time) we implement new ThingCriterion and they get picked > up automatically... > > > > > > > > > > > > @Inject > > > private Instance<ThingCriterion> thingCriteria; > > > > > > > > > public List<ValidationProblem> validateList(final ProcessedThing > thing, final InputThing inputThing) { > > > List<ValidationProblem> results = new ArrayList<>(); > > > for (final ThingCriterion criterion : thingCriteria) { > > > results.addAll(criterion.validate(thing, inputThing)); > > > } > > > return results; > > > } > > > > > > > > > Romain, > > > > > > Thanks for your help. Great suggestion will it have better perf then > just putting @ApplicationScoped on my ThingCriterion beans? Probably not > important just curious. > > > > > > cheers > > > > > > On 27 February 2015 at 19:25, Romain Manni-Bucau < > [email protected]> wrote: > > > When I used this pattern I always did (for perf reason but side effect > is behavior is what you want): > > > > > > @PostConstruct > > > private void resolve() { > > > value = instance......get(); > > > } > > > > > > then in the code don't use instance at all but value. > > > > > > > > > > > > Romain Manni-Bucau > > > @rmannibucau | Blog | Github | LinkedIn > > > > > > 2015-02-27 19:15 GMT+01:00 John D. Ament <[email protected]>: > > > Are you calling get() on the Instance with each request (or whatever0 > that comes into this bean? > > > > > > On Fri, Feb 27, 2015 at 1:13 PM Karl Kildén <[email protected]> > wrote: > > > To explain myself further ALL I had on my heap was my > Instance<MyInterface>... and gc released 0.5% memory :) > > > > > > I had 200 000 of them at least. They where supposed to be four > singletons. My idea was inject into @ApplicationScoped and omit to give > them scope because they will be @ApplicationScoped anyways... Seems every > invocation of my @ApplicationScoped bean recreated all instances. > > > > > > What I had was unrecoverable mem leak. Now I could be doing something > stupid or Instance<MyInterface> has a problem or something else... > > > > > > Cheers > > > > > > > > > > > > On 27 February 2015 at 19:05, Romain Manni-Bucau < > [email protected]> wrote: > > > If dependent it will be kept in enclosing bean. > > > Le 27 févr. 2015 19:00, "Lars-Fredrik Smedberg" <[email protected]> > a écrit : > > > > > > So does this mean that there will be a memory leak in the case Karl > described? > > > > > > I have used similar constructs before so im curios (@Inject @Provider > <some dep scoped bean> in an @ApplicationScoped bean and called get () on > the injected provider). > > > > > > I thought for a while that it might get garbage collected when the > created bean is outof scope or maybe then there is no way for @PreDestroy > to be called? > > > > > > Regards > > > LF > > > > > > I thought that the created dep scoped bean would be > > > > > > On Feb 27, 2015 6:07 PM, "Romain Manni-Bucau" <[email protected]> > wrote: > > > Yes. > > > > > > Will be destoyed with the bean where it is injected IIRC so the app > here. > > > > > > Le 27 févr. 2015 16:59, <[email protected]> a écrit : > > > Hello! I have a bean with @ApplicationScoped. When I inject > Instance<MyInterface> instance and my actual beans implementing MyInstance > are dependentscoped they get recreated over and over and are not gc'd. > > > > > > Expected behavior? > > > > > > Cheers > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > Med vänlig hälsning / Best regards > > > > Lars-Fredrik Smedberg > > > > STATEMENT OF CONFIDENTIALITY: > > The information contained in this electronic message and any > > attachments to this message are intended for the exclusive use of the > > address(es) and may contain confidential or privileged information. If > > you are not the intended recipient, please notify Lars-Fredrik Smedberg > > immediately at [email protected], and destroy all copies of this > > message and any attachments. > > -- Med vänlig hälsning / Best regards Lars-Fredrik Smedberg STATEMENT OF CONFIDENTIALITY: The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the address(es) and may contain confidential or privileged information. If you are not the intended recipient, please notify Lars-Fredrik Smedberg immediately at [email protected], and destroy all copies of this message and any attachments.
