views:

117

answers:

3

Hello,

Let's say I have the following interceptor in a SEAM app:

public class MyInterceptor {
  @In
  private Monitor myMonitor;

  @AroundInvoke
  public Object aroundInvoke(InvocationContext ctx) throws Exception {
    try {
      myMonitor.a();
      return ctx.proceed();
    }
    finally {
      myMonitor.b();
    }
  }
}

myMonitor.a() works (so Monitor is correctly injected), myMonitor.b() fails because Monitor is already null. Seam Doc says: "Injected values are disinjected (i.e., set to null) immediately after method completion and outjection."

Is that what is happening? Can I do something to tell SEAM to "not yet" "disinject" the component? I can of course also do something like XContext.get(..), but I'm wondering whether this is a bug or a mistake from my side. thanks!

+1  A: 

Hi,

Try this one instead

Object response = null;

try {
    myMonitor.a();

    response = ctx.proceed();
} finally {
    myMonitor.b();
}

return response;

regards,

Arthur Ronald F D Garcia
+1  A: 

Avoid using injection.

Try working around this problem. I see you have some sort of monitoring going on. Look at this interceptor that captures the amount of time a method is executed in Seam components. Try modifying your code to match that.

It works great! Here is the link

Shervin
@Shervin Good to know (+1), Shervin. Seam Framework: Experience the Evolution of Java EE says you can avoid @In-jection by using a single setter method without no @In annotation.
Arthur Ronald F D Garcia
A: 

Seam is working as advertised.

You could just ignore the disinjection:

public class MyInterceptor {

  private Monitor myMonitor;

  @In
  private void setMonitor(Monitor aMonitor) {
     if (aMonitor != null) {
       myMonitor = aMonitor;
     }
  }


  @AroundInvoke
  public Object aroundInvoke(InvocationContext ctx) throws Exception {
    try {
      myMonitor.a();
      return ctx.proceed();
     }
     finally {
       myMonitor.b();
       myMonitor = null; //perform disinjection yourself
     }
  }
}

The caveat here is that Seam is disinjecting the reference for a reason. Seam wants to control the lifecycle and identity of "myMonitor" and by keeping a reference to it, you are not abiding by your contract with Seam. This could lead to unexpected behavior.

For instance, if myMonitor were for some reason in the Stateless scope, Seam might destroy it before ctx.proceed() returns, leaving you with a reference to a broken proxy. Best advice is to know the scope and lifecycle of what you are retaining since you are "living on the edge."

recampbell
Hmm, sorry but I don't really get how your code would help me. My problem is that in the line "myMonitor.b()", myMonitor is null. (what you describe in your second paragraph is what happens). I don't see how this is "Seam working as advertised", since I assume that "method completion" includes the execution of all finally {} blocks - or am I wrong?
wilth