= JMS Resources and MDB Container
:index-group: Configuration
:jbake-date: 2018-12-05
:jbake-type: page
:jbake-status: published


== External ActiveMQ Broker

[source,xml]
----
<tomee>
    <Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
        # Do not start the embedded ActiveMQ broker
        BrokerXmlConfig  =
        ServerUrl = tcp://someHostName:61616
    </Resource>

    <Resource id="MyJmsConnectionFactory" type="jakarta.jms.ConnectionFactory">
        ResourceAdapter = MyJmsResourceAdapter
    </Resource>

    <Container id="MyJmsMdbContainer" ctype="MESSAGE">
        ResourceAdapter = MyJmsResourceAdapter
    </Container>

    <Resource id="FooQueue" type="jakarta.jms.Queue"/>
    <Resource id="BarTopic" type="jakarta.jms.Topic"/>
</tomee>
----

The `ServerUrl` would be changed to point to the host and port of the
ActiveMQ process. The various URL formats that ActiveMQ supports also
work, such as 'failover:'.

== Internal ActiveMQ Broker

[source,xml]
----
<tomee>
    <Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig =  broker:(tcp://someHostName:61616)
        ServerUrl       =  tcp://someHostName:61616
    </Resource>

    <Resource id="MyJmsConnectionFactory" type="jakarta.jms.ConnectionFactory">
        ResourceAdapter = MyJmsResourceAdapter
    </Resource>

    <Container id="MyJmsMdbContainer" ctype="MESSAGE">
        ResourceAdapter = MyJmsResourceAdapter
    </Container>

    <Resource id="FooQueue" type="jakarta.jms.Queue"/>
    <Resource id="BarTopic" type="jakarta.jms.Topic"/>
</tomee>
----

The `BrokerXmlConfig` tells ActiveMQ to start on the tcp host/port
`someHostName` and `61616`

=== Internal ActiveMQ Broker with JDBC Persistence

Adding the `DataSource` property to your `ActiveMQResourceAdapter`
config will automatically set up JDBC Persistence using the
`org.apache.activemq.store.jdbc.JDBCPersistenceAdapter`

[source,xml]
----
<tomee>
    <Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig =  broker:(tcp://someHostName:61616)
        ServerUrl       =  tcp://someHostName:61616
        DataSource      =  MyDataSource
    </Resource>

    <Resource id="MyDataSource" type="javax.sql.DataSource">
        JdbcDriver  = org.hsqldb.jdbcDriver.
        JdbcUrl     = jdbc:hsqldb:file:data/hsqldb/hsqldb.
        UserName    = sa
        Password    = foo
    </Resource>
</tomee>
----

=== Internal ActiveMQ Broker with activemq.xml

The activemq.xml file format requires a number of Spring dependencies,
and is therefore not included in the distribution by default. This is
purley due to the fact that this ActiveMQ file format is parsed using
Spring libraries and this is beyond our control. However, the advantage
is opening up the door to the huge number of configuration options
available found here: http://activemq.apache.org/xml-configuration.html.

This support can be enabled by adding the right libraries and creating
an link:activemq.xml[`[tomee]/conf/activemq.xml`] file (Click the link
for a basic example).

Add the following jars to the `tomee/lib/` directory:

* http://repo1.maven.org/maven2/org/springframework/spring-beans/3.2.9.RELEASE/spring-beans-3.2.9.RELEASE.jar[spring-beans-3.2.9.RELEASE.jar]
* http://repo1.maven.org/maven2/org/springframework/spring-context/3.2.9.RELEASE/spring-context-3.2.9.RELEASE.jar[spring-context-3.2.9.RELEASE.jar]
* http://repo1.maven.org/maven2/org/springframework/spring-core/3.2.9.RELEASE/spring-core-3.2.9.RELEASE.jar[spring-core-3.2.9.RELEASE.jar]
* http://repo1.maven.org/maven2/org/springframework/spring-web/3.2.9.RELEASE/spring-web-3.2.9.RELEASE.jar[spring-web-3.2.9.RELEASE.jar]
* http://repo1.maven.org/maven2/org/apache/xbean/xbean-spring/3.2.9.RELEASE/xbean-spring-3.9.jar[xbean-spring-3.9.jar]

Later versions should work, but have not been tested.

Create an link:activemq.xml[activemq.xml file] in
`[tomee]/conf/activemq.xml`.

Then use the `xbean:file:` url prefix in the `BrokerXmlConfig` as shown
belog.

[source,xml]
----
<tomee>
    <Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig =  xbean:file:conf/activemq.xml
        ServerUrl       =  tcp://someHostName:61616
    </Resource>

    <Resource id="MyJmsConnectionFactory" type="jakarta.jms.ConnectionFactory">
        ResourceAdapter = MyJmsResourceAdapter
    </Resource>

    <Container id="MyJmsMdbContainer" ctype="MESSAGE">
        ResourceAdapter = MyJmsResourceAdapter
    </Container>

    <Resource id="FooQueue" type="jakarta.jms.Queue"/>
    <Resource id="BarTopic" type="jakarta.jms.Topic"/>
</tomee>
----

Finally, restart the server.

== Configuration via System properties

The same can be done via properties in an embedded configuration, via
the `conf/system.properties` file or on the command line via `-D` flags.

[source,java]
----
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());

p.put("MyJmsResourceAdapter", "new://Resource?type=ActiveMQResourceAdapter");
p.put("MyJmsResourceAdapter.ServerUrl", "tcp://someHostName:61616");
p.put("MyJmsResourceAdapter.BrokerXmlConfig", "");

p.put("MyJmsConnectionFactory", "new://Resource?type=jakarta.jms.ConnectionFactory");
p.put("MyJmsConnectionFactory.ResourceAdapter", "MyJmsResourceAdapter");

p.put("MyJmsMdbContainer", "new://Container?type=MESSAGE");
p.put("MyJmsMdbContainer.ResourceAdapter", "MyJmsResourceAdapter");

p.put("FooQueue", "new://Resource?type=jakarta.jms.Queue");
p.put("BarTopic", "new://Resource?type=jakarta.jms.Topic");

InitialContext context = new InitialContext(p);
----

== Global lookup of JMS Resources

From anywhere in the same VM as the EJB Container you could look up the
above resources like so:

[source,properties]
----
jakarta.jms.ConnectionFactory cf = (ConnectionFactory)
        context.lookup("openejb:Resource/MyJmsConnectionFactory");

jakarta.jms.Queue queue = (Queue) context.lookup("openejb:Resource/FooQueue");
jakarta.jms.Topic topic = (Topic) context.lookup("openejb:Resource/BarTopic");
----

== MDB ActivationConfig

Here, the value for `destination` is the physical name of the desired
destination. The value for `destinationType` is the class name that
defines the type of destination. It should be `jakarta.jms.Queue` or
`jakarta.jms.Topic`.

The Activation Spec properties that can be configured are:

[.table.table-bordered,options="header"]
|===
|Property Name |Required |Default Value |Description

|*acknowledgeMode*
|no
|_Auto-acknowledge_
|The JMS Acknowledgement mode to use. Valid values are: Auto-acknowledge or Dups-ok-acknowledge

|*clientId*
|no
|_set in resource adapter_
|The JMS Client ID to use (only really required for durable topics)

|*destinationType*
|yes
|_null_
|The type of destination; a queue or topic

|*destination*
|yes
|_null_
|The destination name (queue or topic name)

|*enableBatch*
|no
|_false_
|Used to enable transaction batching for increased performance

|*maxMessagesPerBatch*
|no
|_10_
|The number of messages per transaction batch

|*maxMessagesPerSessions*
|no
|_10_
|This is actually the prefetch size for the subscription. (Yes, badly named).

|*maxSessions*
|no
|_10_
|The maximum number of concurrent sessions to use

|*messageSelector*
|no
|null
|Message Selector to use on the subscription to perform content based routing filtering the messages

|*noLocal*
|no
|_false_
|Only required for topic subscriptions; indicates if locally published messages should be included in the subscription or not

|*password*
|no
|_set in resource adapter_
|The password for the JMS connection

|*subscriptionDurability*
|no
|_NonDurable_
|Whether or not a durable (topic) subscription is required. Valid values are: Durable or NonDurable

|*subscriptionName*
|no
|_null_
|The name of the durable subscriber. Only used for durable topics and combined with the clientID to uniquely identify the durable topic subscription

|*userName*
|no
|_set in resource adapter_
|The user for the JMS connection

|*useRAManagedTransaction*
|no
|_false_
|Typically, a resource adapter delivers messages to an endpoint which is managed by a container. Normally, this container likes to be the one that wants to control the transaction that the inbound message is being delivered on. But sometimes, you want to deliver to a simpler container system that will not be controlling the inbound transaction. In these cases, if you set useRAManagedTransaction to true, the resource adapter will commit the transaction if no exception was generated from the MessageListener and rollback if an exception is thrown.

|*initialRedeliveryDelay*
|no
|_1000_
|The delay before redeliveries start. Also configurable on the ResourceAdapter

|*maximumRedeliveries*
|no
|_5_
|The maximum number of redeliveries or -1 for no maximum. Also configurable on the ResourceAdapter

|*redeliveryBackOffMultiplier*
|no
|_5_
|The multiplier to use if exponential back off is enabled. Also configurable on the ResourceAdapter

|*redeliveryUseExponentialBackOff*
|no
|_false_
|To enable exponential backoff. Also configurable on the ResourceAdapter

|===
