Updating message beans
As part of our review of EJB in working on passing the JavaEE 6 TCK for the Web Profile, we’ve been talking about how we’d like to improve the next generation of EJB message driven beans for JavaEE 7.
Message driven beans hook up application code to reliably receive messages from a messaging queue, like a heavyweight order-fulfilment system for a retail/manufacturing site. The application’s listener beans receive messages, process the message, and then ask the queue for the next message. Like the pooled bean, message-driven beans use a pool of Java classes to process several messages at once, while limiting the total concurrency to something like 5 simultaneous messages.
We’d like to simplify the application listener to queue selection, and support application objects better, rather than keeping tied to the JMS Message interface. If we do this right, we’ll encourage more focused code, and more flexible configuration. The basic tool is to take the CDI @Observes as a design idea.
The CDI @Observes registers an application method as a listener for CDI Events. For message-driven beans, we want to do the same thing for messages. So we need to select the objects we’re interested in, and select the queue we’re attaching to. The application code would look something like:
The @MessageObserves marks the onMessage as a queue listener. The BlueMessage selects the kinds of messages we’re able to support, making the messaging system dispatch to the proper application method, rather than forcing the application itself to select messages. The @BlueQueue is an application-specific CDI qualifier that selects the configured queue. The CDI qualifier is important because we want to select the queue logically, by its function in our application, not by an arbitrary name. With this design, message-driven beans would be a CDI extension. When the MDB system sees a @MessageObserves annotation, it looks up a queue specified by the @BlueQueue qualifier, and creates the MDB pooled beans as listeners for queue events. In our brainstorming session, we thought the queue selection by the functional qualifier would make configuration more flexible (unlike the fairly rigid @ActivationSpec annotation), and the method type would more clearly expose the application intent, unlike the opaque Message object of JMS.
@BlueQueue
void onMessage(@MessageObserves BlueMessage message);
