The EJB standard took a giant step between version 2.1 and 3.0 - the same step is (in our eyes) still missing in the JMS standard: To provide a simple to use, pure Java interface solution to remote calls... only asynchronous in this case. Even Spring has not a solution satisfying us, so we at 1&1 have started this project.
We want to evolve it into a standard in some way (in some fits of megalomania I think it maybe even become part of JMS 2.0 or Java EE 7 one day ;-). As a first step we make it publicly available so everybody can take a look at what we're up to. We welcome any feedback - from feature requests to patches, from downloads to success stories. Yes, downloading is feedback, too: Having lot's of users and still no comments could mean that the project is just perfect, couldn't it? ;-)
Business code should concentrate on the message that is to be sent or what it has to do when a message is received. What technology is used, where the message is going to or coming from, how the message is transformed, etc. has to be provided by a configurable adapter layer and injected into the business code.
Moving from JMS 1.1 to the MessageApi means:
The idea is actually quite simple: You add the @MessageApi
annotation to an interface that has only methods that return void
and don't declare any exceptions - remember: they are going the be sent asynchronously. An annotation processor converts all methods in that interface into POJOs, e.g. it transforms a method public void createCustomer(String firstName, String lastName)
into a CreateCustomer
POJO with the two parameters as properties (i.e. it has a getFirstName()
method). This POJO is immutable, contains hashCode
, equals
, and toString
methods, and is properly annotated for JAXB. You then package the interface and the generated POJOs into an API jar to be called by clients and implemented by services.
At runtime, the container injects a proxy for that interface into the client business code. So when you call e.g. the createCustomer
method, the proxy converts the call into an instance of the POJO, marshalls it using JAXB, creates a text message containing it, and sends it to the configured queue. The business code can rely on two things: The call is asynchronous (i.e. only technical stuff actually happens within the method call) and the call is transactional (i.e. if the whole transaction fails for any reason, no message is sent either).
On the receiver side, an MDB receives the message, unmarshalls the POJO, and calls the corresponding method in your business code that implements the messaging interface. Also the assumptions the business code can make are mirrored: The message was asynchronous (i.e. the calling business code has probably long finished) and the call is transactional (i.e. if the whole transaction fails for any reason, the message is not consumed).
In order to communicate with 'legacy' JMS participants, you can configure the MessageApi adapter to send or receive mapped messages, and if you will, how to map the message fields.
The MessageApi is already reality: Version 1.0 is in production use internally at 1&1 since August 2010; in November 2010 we have already used it to send or receive over 250.000 messages. The work required to release it open source on java.net
resulted in version 1.1 released in December 2010 (deployment on the java.net maven repository still has to happen, as that project is currently migrated to the Kenai infrastructure).
New features will then be added to versions starting with 1.2. We'll publish more detailed plans as soon as java.net
was migrated to the Kenai infrastructure. One of the most important features we want to add is the automatic configuration with a registry: When you deploy an implementation of an interface annotated as MessageApi
, the container creates a queue and registers it in a registry using two coordinates: The fully qualified name of the interface and the version of the jar that contains the interface. When you deploy a client for those coordinates, the container finds the correct queue to send these messages to and connects it with your business code... leaving not much left for you to do, but to write business code ;-)
You can participate in a variety of ways: