We have a lightweight, easily embeddable Spring based JCA container which allows us to provide MDB like functionality inside any Java application without requiring a full EJB container.
This allows us to support message driven pojos using dependency injection for efficient JMS consumption together with pooling of the pojos using lightweight containers rather than relying on EJB.
The JCA container also makes it easy to programatically at runtime create new message driven pojos rather than relying on the fixed deployment-time only option with EJB.
Here is an example of the Spring XML to deploy a pojo (EchoBean) on an inbound JMS subscription, on a topic in this particular example.
Firstly we can create as many JCAContainer instances as we need; currently we create one per JCA Resource Adapter (i.e. JMS provider). The JCAContainer also uses a WorkManager which is JCA speak for a bunch of thread pools. We can share the WorkManager across JCAContainer instances or create one per JCAContainer.
Once we have a JCAContainer we can add as many JCAConnector instances to it, via the addConnector factory method, each one representing a JMS subscription and providing a pool of POJOs to process the message. The subscription details are specified by an activationSpec property which is a bean typically dependent on the JMS provider; this allows providers to add new extensions while leaving your application code pure JMS.
Notice that the regular Spring pooling mechanism, the targetSource property, is used to pool the actual POJO and that Spring uses Dependency Injection to construct instances of the POJO.
Note you must set the singleton flag to false for the POJOs if they are not thread safe.
To be able to use the JCA container, you just need the following jars on your classpath
Note the classes and resources in activemq-container.jar are not included in activemq.jar
To use the JCA Container please use the 2.x code release. Several problems were found and fixed with the 1.x branch of code.
By default the ActiveMQ Resource Adapter will try to connect to a remote broker (ie. tcp://localhost:61616). Also if you want to set how the broker is configured via XML then try the brokerXmlConfig property.
Note: In AMQ 3.x the default behavior is the ActiveMQ resource adapter will create an embedded broker