March 29, 2016

Asynchronous Support in Java EE 6

Introduction

Java EE 6 comes with two ready to use asynchronous technique:

  • EJB
  • Servlet

EJB

Example

@Stateless
public class OrderBean {

    @Asynchronous
    public Future<String> processPayment(Order order) throws PaymentException {
        ...
        String status = ...;
        return new AsyncResult<String>(status);
    }
}

Oracle Java EE 6 Tutorial: Asynchronous Method Invocation

Oracle Java EE 6 Tutorial: Using Alternatives in CDI Applications

Servlet

This asynchronous feature is less documented, but could be used for example a servlet that generates a PDF or some other heavy computing.

Example

package se.magnuskkarlsson.example.servlet;

import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/MyAsyncServlet", asyncSupported = true)
public class MyAsyncServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        AsyncContext ac = request.startAsync(request, response);
        ac.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onComplete");
            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onTimeout");
                event.getAsyncContext().complete();
            }

            @Override
            public void onError(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onError");
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onStartAsync");
            }
        });

        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2));
        executor.execute(new MyAsyncService(ac));
    }

    class MyAsyncService implements Runnable {

        AsyncContext ac;

        public MyAsyncService(AsyncContext ac) {
            this.ac = ac;
        }

        @Override
        public void run() {
            try {
                ac.getResponse().getWriter()
                        .println("Running inside MyAsyncService");
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
            ac.complete();
        }
    }
}

No comments: