Pergunta

I'm writing a JEE7/Glassfish 4 application that reads data from an external queue (RabbitMQ) and processes it. It needs a method (I suppose an EJB method) that contains a loop that never exits that reads the queue. I suppose since this loop never exits, it needs to be on a separate thread. My question is, what is the correct way to do this in a JEE7 application?

This may be obvious, but the ReadQueue() method needs to start automatically when the app starts and must keep running permanently.

Is the ManagedExecutorService appropriate for this?

Foi útil?

Solução

ManagedExecutorService is exactly what you want to use for this.

The availability of this service in JEE is a great benefit. In the past, we basically just ignored the guidelines and managed all of this stuff ourselves.

The MES allows you to capture the context information of the invoking component, and tie your task in to the life cycle of the container. These are both very important in the JEE environment.

As to where to start the task, you basically have two options.

One, you can use a ServletContextListener, and have that kick off the task during container startup.

Two, you can use an @Singleton EJB, and tie in to its lifecycle methods to start your task.

If you start the task up from the ServletContextListener, then the task will run as if it's in the WAR environment. If you start it up from the @Singleton, it will run within the Session Beans environment (this mostly relates to how the JNDI appears).

Either way, you only need to worry about starting the task via these mechanisms. You should rely on the ManagedTaskListener.taskAborted interface method to shut your task down.

In theory you can work with the Thread.interrupt that is sent to your task during shut down. I've never had good luck with that myself, I rely on an external mechanism to tell the long running tasks to shut off.

I wish I could give first hand experience with this new facility, but I haven't had an opportunity to try it out yet. But from the spec, this is what you want to do.

Outras dicas

To start a thread with an infinite loop that polls the queue periodically is usually not a good idea. The nature of queues suggests an async, event-driven processing. For such problems in the JEE world you have MDBs. The only issue here is that MDB requires a JMS queue provider but RabbitMQ is using a different protocol (AMQP). You need a JMS-AMQP bridge to make this work. Could be Qpid JMS but no guarantee that it will work.

Here is one way to create a thread that never exits:

public class HelloRunnable implements Runnable {
    public void run() {
        while (true) {
            // do ReadQueue() here
        }
    }
    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top