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:

@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();
  }

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.

Reply via email to