Tuesday, July 16, 2013

Just an idea - programmatic registration of MDBs

Just an idea - programmatic registration of MDBs

So, I'm throwing an idea out there, soliciting feedback.  Why can't MDBs be programmatically registered in the container?

My idea is that an MDB can be a CDI object (rather than an EJB object),

I have a simple GitHub project around this idea here, if you want to check it out (still need to maven-ize it): https://github.com/johnament/jms-mdb-config

The first thing to point out is that MDBs are the main way to support message processing in JMS in a Java EE application server.  It's not possible to setup a message listener due to the container restriction around unmanaged threads.

The idea is to generally provide MDB support programmatically.  This is something very useful from both a framework standpoint and an application developer standpoint.  This allows cleaner support for lambda expressions, as well as give a way to dynamically bind MDBs based on runtime settings.  It allows you to on the fly change your bindings (of course, this is assuming that support can be added for it).

In the late days of Java EE 7, a change to MDBs was introduced to allow an MDB to be bound at a method level of an object.   While this is a great feature, it still doesn't tackle what I think most people need from an MDB - dynamic support.  I'm using a PaaS example in my setup - where we need to dynamically create a queue per tenant to do work (to physically separate their data) and then register that queue when ready to a new MDB instance.

There are a few things this doesn't seem to support as well.  The first is pooling.  No way to create many instances in the one case and the other case uses CDI rules for instantiation.  I think both are OK, since we're not talking about super heavyweight objects.  Though we may run into an issue if too many messages come on the thread.  Realistically, I haven't handled an implementation that wasn't singleton in nature, so I think this isn't a huge loss.  The second is that this doesn't give an option of doing the configuration from annotations.  I think this could be solved by introducing annotations @JMSConfigurationProvider and @JMSListenerMethod, so that the container scanned these automatically on start up.

Of course, these are all JMS specific annotations and interfaces.  I would imagine a revised MDB spec like this would indicate that a configuration object may be polled and return a typed configuration based on what it's handling, so JMSConfiguration would be that for JMS (and if we did support other types of MDBs, they would each have their own configuration).

Another thing that this helps with is in the SE world.  We now have a standard interface to program against for binding of listeners.  While this would be an MDB in SE, it could apply to a remote JMS connection.  This could remove the need for binding MessageListeners.