Friday, October 1, 2010 Connector/Bean API : JAX-RS and beyond

It isn't commonly known that MessageDrivenBeans (MDBs) are not directly tied to the Java Message Service (JMS). In fact, they are tied to the Java EE Connector Architecture. It's even less commonly known that MDBs are not necessarily asynchronous. It's really the Connector that drives the communication style.
Overall, it is a very cool model that does allow for some pretty impressive and standard extension to any compliant Java EE platform. It is, however, incredibly underused. With a few changes to the model, it could be made to support even things like JAX-RS. Let's break it down.
The touchpoints between the Connector and the MDB are the ActivationSpec/ActivationConfig and the MessageListener interface. Using a fictitious "Email" Connector idea, let's see how this looks.
EmailConsumer (MessageListener) interface*
package org.superemail.connector;

// other imports...
public interface EmailConsumer {
    public void receiveEmail(Properties headers, String body);
EmailAccountInfo (ActivationSpec) class
package org.superemail.connector;
 * This class is basically an old-style JavaBean with get/set for each property
public class EmailAccountInfo implements javax.resource.spi.ActivationSpec {

    private String address;

    public String getAddress() {
        return address;

    public void setAddress(String address) {
        this.address = address;

    public void validate() throws InvalidPropertyException {
That's it for the Connector (aside from the Connector itself). I have left out a little detail on the ActivationSpec, we'll cover that later.
Now for the MDB's side of things. The MDB needs to implement the Connector's EmailConsumer interface and configure the Connector'sEmailAccountInfo JavaBean which is done via the activation-config tag of the ejb-jar.xml or via @ActivationConfigPropertyannotations in the @MessageDriven declaration.
@MessageDriven(activationConfig = 
                propertyName = "address", 
                propertyValue = "")
public class EmailBean implements EmailConsumer {

    public void init() {

    public void receiveEmail(Properties headers, String body) {
        // do your thing!
Done. Those are the basics. The Connector supplies a MessageListener interface and an ActivationConfig JavaBean, the MDB implements the interface and configures the JavaBean via the loosely-typed @ActivationConfigProperty.
There are a few things that prevent this model from reaching its true potential:
  • Metadata is loosely typed in the bean code
  • Only class-level metadata is allowed, not method-level
  • Requiring an interface can limit expressiveness
Let's see how life might look if we eliminate the JavaBean and allow the Connector to instead supply an annotation.
package org.superemail.connector;
public @interface EmailAccountInfo {
    String address();
Side Note: The original javax.resource.spi.ActivationSpec interface has a 'validate()' method on it to validate the JavaBean. A clear update to that part of the API would be to instead use the Bean Validation API.
Which gives us a bean that might look like this:
@EmailAccountInfo(address = "")
public static class EmailBean implements EmailConsumer {

    public void init() {

    public void receiveEmail(Properties headers, String body) {
        // do your thing!
Now we're getting somewhere!
Ok, let's get rid of that message listener interface and image our Email Connector uses a very JAX-RS inspired API for consuming emails. If you know a little JAX-RS you'll see where I'm going with this.
@EmailAccountInfo(address = "")
public static class EmailBean {

    public void init() {

    @Deliver @Header("Subject: {subject}")
    public void receiveEmail(@HeaderParam("subject") String subject, @Body String body) {
        // do your thing!
Pretty neat, huh?
Side note: For the rare few of you that speak Connector implementation, instead of giving your Resource Adapter a MessageEndpoint that is a proxy that only implements the MessageListener interface and the standard MessageEndpoint interface, the Container would instead give you an @LocalBean proxy that also implements MessageEndpoint. If you're thinking that an API like that would be great to use... imagine with the above changes you could make that API ... and use it in any compliant Java EE platform. Maybe even submit your own JSR if you came up with something great.
Truthfully speaking, it's the Connector who controls the lifecycle of the bean (MDB). The Connector API already allows for the Connector to say to the Container, "create me a bean" and "destroy this bean". So really, we don't need @MessageDriven anymore. Instead we can do this:
import javax.annotation.ManagedBean;

@EmailAccountInfo(address = "")
public static class EmailBean {
 // ....
That's a little more modern and perhaps a bit clearer.
At this point, we have a generic API to hook arbitrary "Connectors" up to arbitrary "Beans" that are managed by a container. Were this the case when JAX-RS was created, they wouldn't have had to put so much effort into duplicating all the services that people who have managed beans expect: injection of resources, lifecycle callbacks, interceptors.
Summary: A few improvements to the expressiveness of the metadata passed between a Bean and its Connector could kick the MDB/Connector model into the mainstream as was the intention of the API from the beginning. New specifications could be created based on this model and be introduced incrementally as they are developed and needed.
The impact of fully opening up the Bean metadata to the Connector is quite deep and wide and likely not something that will scream at you immediately. Ask yourself, could something like the new EJB 3.1 @Schedule API have been done with a Connector/Bean model like this? To some extent probably it could. Certainly there already existed a few Quartz Connectors out there prior to the introduction of @Schedule.
Take a moment to daydream. What kind of Connectors could you create with this model?

UPDATE - Feb 7th, 2013

Save this proposal.  Without more voices it will be delayed till Java EE 8.  Let's not wait 4 years!  Take action and celebrate the Java Community Process openness by showing your support for including this in Java EE 7.  Act now.



lightguardjp said...

Could something like @Connector or something be used instead of @ManagedBean? Seems like you should be able to do something like this with CDI

Narender Godara said...

Packers and movers Goa
Packers and movers Gorakhpur
Packers and movers Gurgaon
Packers and movers Hadapsar pune

Chitransh Andola said...

Packers and Movers India
Packers and Movers in Bangalore
Packers and Movers in Delhi
Packers and Movers in Hyderabad
Packers and Movers in Mumbai
Packers and Movers in Chennai
Packers and Movers in Pune
Packers and Movers in Noida
Packers and Movers in Gurgaon
Packers and Movers in Ghaziabad
Packers and Movers in Faridabad

Mary Brown said...

Java EE article is practical oriented and real time examples. How Java EE address the enterprise development is very important. for that you need a practical orieneted Java Training you need.

Online Java Training
Online Java Training from India
Java Training Institutes in Chennai
Java Training in Chennai
Java Training

The Ahir said...

Happy New Year 2016 Messages

Happy New Year 2016 Images

New Year Wishes

IPL 2016 Schedule

IPL Schedule 2016

IPL 9 Schedule

IPL 2016

IPL 2016 Schedule

IPL Fixtures 2016

IPL 2016 Live Score

IPL 2016 Live

2016 IPL Schedule

ICC T20 World Cup 2016 Schedule

T20 World Cup 2016 Live Streaming

T20 World Cup 2016

Cricket World Cup 2016 Schedule

T20 Cricket World Cup 2016 Schedule

National Flag of India

indian national flag

indian flag pictures

national flag images

indian flags

Govt Jobs Jobs Recruitment Govt Jobs

Latest Jobs Jobs Latest Recruitment Govt Jobs