Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java @Asynchronous Methods: not running async

I try to get an async process running. Based on this example: http://tomee.apache.org/examples-trunk/async-methods/README.html

But the method addWorkflow(Workflow workflow) will only return when the code in run(Workflow workflow) is fully completed.

Then when it returns and result.get(); is called I'll get the exception:

Caused by: java.lang.IllegalStateException: Object does not represent an acutal Future

Any suggestion what I'm missing?

@Singleton
public class WorkflowProcessor {

@EJB
private  WorkflowManager workflowManager;

private final static Logger log = Logger.getLogger(WorkflowProcessor.class.getName());



public void runWorkflows(Collection<Workflow> workflows) throws Exception{  
    final long start = System.nanoTime();
    final long numberOfWorkflows = workflows.size();
    Collection<Future<Workflow>> asyncWorkflows = new ArrayList<>();

    for(Workflow workflow : workflows){
        Future<Workflow> w = addWorkflow(workflow);
        asyncWorkflows.add(w);
    }    
    log.log(Level.INFO, "workflow jobs added {0}", new Object[]{numberOfWorkflows});
    for(Future<Workflow> result : asyncWorkflows){
       result.get();
    }

    final long total = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
    log.log(Level.INFO, "WorkflowProcessor->runWorkflows {0} workflows completed in:{1}", new Object[]{numberOfWorkflows, total});

}

@Asynchronous
@Lock(LockType.READ)
@AccessTimeout(-1)
private Future<Workflow> addWorkflow(Workflow workflow){

    run(workflow);

    return new AsyncResult<Workflow>(workflow);                
}


private void run(Workflow workflow){
    this.workflowManager.runWorkflow(workflow);
}
like image 898
busyBee Avatar asked Oct 14 '25 16:10

busyBee


1 Answers

So the normal way would be to have the @Asynchronous method in another bean from the caller method.

@Stateless
public class ComputationProcessor {

 @Asynchronous
 public Future<Data> performComputation {
   return new AsyncResult<Data>(null);
 }
}

@Stateless
public class ComputationService {

 @Inject
 private ComputationProcessor mProcessor;

 public void ...() {
   Future<Data> result = mProcessor.performComputation();
   ...
 }
}

As you discovered, it won't work if the @Asynchronous method is in the same bean than the caller.

like image 105
Emmanuel Touzery Avatar answered Oct 17 '25 04:10

Emmanuel Touzery



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!