# Going Async with EJBs

EJBs provide support for asynchronous execution of business logic wherein the calling thread (invoking the EJB business method) is released and the actual processing takes place in a background thread which is managed by the EJB container itself.

The EJB specification provided us the following options

* Asynchronous Beans
* Message Driven Beans

## `@Asynchronous`

Using MDBs (along with a full fledged JMS infrastructure setup) is not something which you would want to commit to, if all you need is a few methods to be invoked asynchronously. In case you do not need strict decoupling b/w sender and receiver and the rich features of enterprise messaging offered by JMS, an easier way of adopting the asynchronous processing paradigm is via the `@Asynchronous` annotation.

```
package ejbap.async;

import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

@Stateless
@Asynchronous
public class EmailService {

    public void sendMail() {

        System.out.println("Sending email......");
        try {
            //for sample purposes ONLY
            Thread.sleep(5000);
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }
    }

}
```

In the above example, the annotated method returns **void**. One also can return a parameterized `java.util.concurrent.Future` object i.e. `Future<T>`. Think of it like a **tracking ID** for your order - you can invoke methods on it to introspect the status of the asynchronous invocation or even cancel your it !

```
package ejbap.async;

import java.util.UUID;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

@Stateless
public class DataService {

    @Asynchronous
    public Future<String> fetch() {
        System.out.println("Invocation thread -- " + Thread.currentThread().getName());
        return new AsyncResult<>(longRunningMethod());
    }

    private String longRunningMethod() {
        System.out.println("Async execution thread -- " 
                + Thread.currentThread().getName());

        try {
            //for sample purposes ONLY
            Thread.sleep(5000);

        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }

        return UUID.randomUUID().toString();
    }
}
```

> `@Asynchronous` is applicable on individual methods as well as classes. In case it is used on a class, all the methods of that EJB would execute asynchronously

## `@ActivationConfigProperty`

This annotation is used to declaratively configure a Message driven bean. It accepts **name value pairs** where the name represents an attribute

> Message Driven Beans are powered by the `@MessageDriven` annotation. Please refer to the **EJB Core** chapter for a detailed discussion on this.

```
package ejbap.async;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationLookup",
            propertyValue = "java:comp/env/orderQueue"),
    @ActivationConfigProperty(propertyName = "destinationType",
            propertyValue = "javax.jms.Queue")
})
public class MDBWithActivationConfig implements MessageListener{

    @Override
    public void onMessage(Message msg) {
        try {
            emailOrderDetails(msg);
        } catch (JMSException ex) {
            throw new RuntimeException(ex);
        }
    }

    private void emailOrderDetails(Message msg) throws JMSException{
        //logic to send order details...
    }

}
```

As you noticed, the **destinationType** and **destinationLookup** attributes were used in the above example. There are a set of standard attributes which are applicable for Message driven beans which listen to JMS destinations (topics and queues)

* **messageSelector**: specifies selectors to be used for filtration
* **connectionFactoryLookup**: connection factory of the JMS provider
* **clientId**: used while connecting to JMS provider
* **subscriptionName**: name of the durable subscription in case the MDB is configured to listen to a Topic
* **subscriptionDurability**: type of subscription, either Durable or NonDurable
* **acknowledgeMode**: acknowledgement mode to be used, either Auto\_acknowledge or Dups\_ok\_acknowledge

## Looking ahead ...

We'll dive into the eager initilization feature provided by Singleton EJBs.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abhishek-gupta.gitbook.io/ejb-annotations-primer/going-async-with-ejbs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
