Why does javax.ejb.AsyncResult.isDone always throws exception?

asynchronous, future, jakarta-ee, java

Solution

So, your question is "is it possible to use java ee asynchronous method invocation?" The answer is yes. And the 2 little bits of code in your question are correct. To fully diagnose what has gone wrong in your case, however, we would probably need to see more of the code.

A possibility is that you are not using the annotation "correctly". A super short code example of how is used can be read here: https://tomee.apache.org/examples-trunk/async-methods/README.html

The important information on that example is that your Asynchronous method has to be declared an Singleton or Stateless bean (let's call it container bean), and in a different bean (or Servlet, or POJO with access to the right JNDI context, like in the link above) that we can call the client you make a call to your container bean. So to be clear, your for loop is in the client. Then your `AsyncResult` will behave like you want it to.

If you read the javadoc you linked to carefully, it says:

The value specified in the constructor will be retrieved by the container and made available to the client.

and

none of its instance methods should be called by the application

This means is that the `AsyncResult` class is sort of a "dumb wrapper" to let you implement the interface easily, but is not supposed to be used "for real".

Please notice that using the `ExecutorService` is the way to perform asynchronous calls when you are not implementing a EJB, or are outside a EJB container. The fact that is working for you makes me thing that you have a direct reference to the container class, instead of via the `@EJB` annotation or by a JNDI lookup.

Problem

I think I misunderstand java ee asynchronous method invocation. I'm following the idea from this official tutorial. For void methods it's fine, but I want my asyncronous method to return a value: ``` @Asynchronous public Future<String> processPayment(Order order) { ... String status = ...; return new AsyncResult<String>(status); } ``` I have many such long running tasks in background, so I collect `List<Future<String>>` and loop through them to check if the task is completed. I do this check by ``` for(Future<String> future: listOfFutures) { if(future.isDone()) // do something } ``` But the code fails with `IllegalStateException:"Object does not represent an acutal Future"` when the method `AsyncResult.isDone()` gets called. Well, then I read this and it made me very confused: official tutorial says "Use AsyncResult.isDone()" to check the status of asynchronous method whereas oficial javadoc says "Don't dare using AsyncResult.isDone()". I know that I could use `FutureTask<T>` together with `Callable<T>`, but this is java se part. Could you explain me if it is possible to use java ee asynchronous method invocation? Thank you! P.S. I'm using Glassfish 3.1.2 and EJB 3.1

Original source

Related problems