Home > database >  Payara @Asynchronous not asynchronous
Payara @Asynchronous not asynchronous

Time:11-30

I'm working on a project powered by Payara Micro and it is configured by a domain.xml file.

I'm facing an issue with the @Asynchronous annotation.

While the Oracle documentation explains this:

Clients calling asynchronous methods, however, immediately have control returned to them by the enterprise bean container.

https://docs.oracle.com/javaee/7/tutorial/ejb-async001.htm

My @Asynchronous annotated method does not return immediately.

@Path("foo")
public class FooResource {
  @GET
  public String get() {
    System.out.println("Request started");
    this.doSomething();
    System.out.println("Request ended");
    return "Hello world! ";
  }

  @Asynchronous
  public void doSomething() {
    try {
      System.out.println("Long task started");
      Thread.sleep(2000);
      System.out.println("Long task ended");
    } catch (InterruptedException e) {
      System.out.println("Long task failed");
    }
  }
}

In my mind it should result in:

Request started
Long task started
Request ended
Long task ended

but it results in:

Request started
Long task started
Long task ended
Request ended

I published on Github a simple Gradle project to reproduce the behavior here.

CodePudding user response:

Your method invocation will be truly asynchronous if you actually invoke the method of an EJB. The call in your sample is a local method call, completely bypassing the container and its annotation processing.

A proper EJB invocation would require an actual EJB:

@Stateless
class MyEJB {

  @Asynchronous
  public void doSomething() {
    try {
      System.out.println("Long task started");
      Thread.sleep(2000);
      System.out.println("Long task ended");
    } catch (InterruptedException e) {
      System.out.println("Long task failed");
    }
  }
}

... and the method invocation in your resource class:

class MyResource {

@Inject MyEJB myEJB;

@Path("foo")
public class FooResource {
  @GET
  public String get() {
    System.out.println("Request started");
    myEJB.doSomething(); // <-- This is the important change!
    System.out.println("Request ended");
    return "Hello world! ";
  }
}
  • Related