users@glassfish.java.net

[gf-users] Re: Future get() method behavior

From: Laird Nelson <ljnelson_at_gmail.com>
Date: Mon, 11 Aug 2014 13:41:52 -0700

On Mon, Aug 11, 2014 at 12:22 PM, Dennis Gesker <dennis_at_gesker.com> wrote:

> You are exactly right. My get() calls a Future<Integer> method decorated
> with @Asynchronous which actually returns AsyncResult() from a SessionBean.
>

OK, now we're getting somewhere.

The following sort of thing will work. Is it what you're doing?

/*
 * (Is your Caller class an EJB itself? Or...?)
 */
public class Caller {

  @EJB // or @Inject
  private Callee callee;

  public void frobnicate() {
    final Future<?> result = callee.caturgiate();
    final Object thing = result.get(); // should block
  }

}


...provided, of course you have some sort of business interface:

public interface Callee {

  public Future<Integer> /* or whatever */ caturgiate();

  public void enscrofulate(); // we'll get to this in a moment


}


...and a bean that implements it:

@Stateless(name = "Callee")
public class CalleeBean implements Callee {

  @Asynchronous
  @Override
  public Future<Integer> caturgiate() {
    return new AsyncResult(Integer.valueOf(42));
  }

  // we'll cover the enscrofulate implementation momentarily


}


Now, what will *not* work that I've seen over and over again in the wild is
(using the example above and just looking at the CalleeBean):

@Stateless(name = "Callee")
public class CalleeBean implements Callee {

  @EJB

  private Callee self; // we'll talk about this in a minute


  @Asynchronous
  @Override
  public Future<Integer> caturgiate() {
    return new AsyncResult(Integer.valueOf(42));
  }

  @Override
  public void enscrofulate() {
    // The following will NOT be an asynchronous method invocation.

    // The caturgiate() method here is a direct method call,

    // not an invocation through a container proxy.

    // To make this work properly, do this instead:
    //

    // this.self.caturgiate(); // no magic; see the self instance variable
    //

    final Future<Integer> caturgiationInterval = this.caturgiate();

    // This will NOT block.
    final Integer interval = caturgiationInterval.get();
  }

}


Although I haven't seen the necessary code in your pastebin or elsewhere,
I'm guessing this is the antipattern you're being burned by.

All code here is typed off the cuff; I'm sure there are (hopefully minor)
typos, etc.

Best,
Laird

-- 
http://about.me/lairdnelson