Friday, June 8, 2012

Remote JMS with JBoss AS 7.1 / HornetQ JMS

When you want to connect to a Queue or Topic on JBoss Application Server 7.1.1 with a remote jms client you can follow the next steps.

First step is to add messaging configuration to the JBoss configuration xml. In this case I will use the standalone configuration.

Open standalone.xml located at jboss-as-7.1.1.Final\standalone\configuration

Add org.jboss.as.messaging to the extensions

<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:1.2">
    <extensions>
        <extension module="org.jboss.as.messaging"/>
        <extension module="org.jboss.as.clustering.infinispan"/>


Add the HornetQ messaging configuration, make sure it is the first xml entry after profile.


    <profile>
        <subsystem xmlns="urn:jboss:domain:messaging:1.1">
            <hornetq-server>
                <persistence-enabled>true</persistence-enabled>
                <journal-file-size>102400</journal-file-size>
                <journal-min-files>2</journal-min-files>

                <connectors>
                    <netty-connector name="netty" socket-binding="messaging"/>
                    <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                        <param key="batch-delay" value="50"/>
                    </netty-connector>
                    <in-vm-connector name="in-vm" server-id="0"/>
                </connectors>

                <acceptors>
                    <netty-acceptor name="netty" socket-binding="messaging"/>
                    <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                        <param key="batch-delay" value="50"/>
                        <param key="direct-deliver" value="false"/>
                    </netty-acceptor>
                    <in-vm-acceptor name="in-vm" server-id="0"/>
                </acceptors>

                <broadcast-groups>
                    <broadcast-group name="bg-group1">
                        <group-address>231.7.7.7</group-address>
                        <group-port>9876</group-port>
                        <broadcast-period>5000</broadcast-period>
                        <connector-ref>
                            netty
                        </connector-ref>
                    </broadcast-group>
                </broadcast-groups>

                <discovery-groups>
                    <discovery-group name="dg-group1">
                        <group-address>231.7.7.7</group-address>
                        <group-port>9876</group-port>
                        <refresh-timeout>10000</refresh-timeout>
                    </discovery-group>
                </discovery-groups>

                <cluster-connections>
                    <cluster-connection name="my-cluster">
                        <address>jms</address>
                        <connector-ref>netty</connector-ref>
                        <discovery-group-ref discovery-group-name="dg-group1"/>
                    </cluster-connection>
                </cluster-connections>

                <security-settings>
                    <security-setting match="#">
                        <permission type="send" roles="guest"/>
                        <permission type="consume" roles="guest"/>
                        <permission type="createNonDurableQueue" roles="guest"/>
                        <permission type="deleteNonDurableQueue" roles="guest"/>
                    </security-setting>
                </security-settings>

                <address-settings>
                    <address-setting match="#">
                        <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                        <expiry-address>jms.queue.ExpiryQueue</expiry-address>
                        <redelivery-delay>0</redelivery-delay>
                        <max-size-bytes>10485760</max-size-bytes>
                        <address-full-policy>BLOCK</address-full-policy>
                        <message-counter-history-day-limit>10</message-counter-history-day-limit>
                        <redistribution-delay>1000</redistribution-delay>
                    </address-setting>
                </address-settings>

                <jms-connection-factories>
                    <connection-factory name="InVmConnectionFactory">
                        <connectors>
                            <connector-ref connector-name="in-vm"/>
                        </connectors>
                        <entries>
                            <entry name="java:/ConnectionFactory"/>
                        </entries>
                    </connection-factory>
                    <connection-factory name="RemoteConnectionFactory">
                        <connectors>
                            <connector-ref connector-name="netty"/>
                        </connectors>
                        <entries>
                            <entry name="RemoteConnectionFactory"/>
                            <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                        </entries>
                    </connection-factory>
                    <pooled-connection-factory name="hornetq-ra">
                        <transaction mode="xa"/>
                        <connectors>
                            <connector-ref connector-name="in-vm"/>
                        </connectors>
                        <entries>
                            <entry name="java:/JmsXA"/>
                        </entries>
                    </pooled-connection-factory>
                </jms-connection-factories>

                <jms-destinations>
                    <jms-queue name="testQueue">
                        <entry name="queue/test"/>
                        <entry name="java:jboss/exported/jms/queue/test"/>
                    </jms-queue>
                </jms-destinations>
            </hornetq-server>
        </subsystem>
        <subsystem xmlns="urn:jboss:domain:logging:1.1">

We will use 

RemoteConnectionFactory as JMS ConnectionFactory with "java:jboss/exported/jms/RemoteConnectionFactory" as JNDI name. Use jms/RemoteConnectionFactory as CF reference in your java client.

queue/test as Queue with as jndi name "java:jboss/exported/jms/queue/test".  Use  jms/queue/test as Queue reference.

For remote it should start with java:jboss/exported/ else these object won't be exposed and then you can't lookup the CF or Queue.

Also for remote we need to create a application user. Go to the bin folder and start add-user.sh
Create a user jms with a password and add this user to the guest role. Guest role has permission for remote and jms. 

Start JBoss with the standalone configuration.


For our java test clients we need to have a jboss and a HornetQ jar file.
First copy jboss-client.jar from the bin/client jboss folder and we need to download the lates HornetQ libraries ( hornetq-2.2.14.Final) . Copy hornetq-jms-client.jar from the HornetQ lib folder.

First the Jms Send Client


Jms Receive Client



In this example I use the same username , password for createQueueConnection
 QueueConnection qcon = qconFactory.createQueueConnection("jms","jboss1");

If you don't do this you will get this error Unable to validate user: null

INFO: JBoss Remoting version 3.2.3.GA
Exception in thread "main" javax.jms.JMSSecurityException: Unable to validate user: null
at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:312)
Caused by: HornetQException[errorCode=105 message=Unable to validate user: null]

To solve this you can also disable messaging security
    <profile>
        <subsystem xmlns="urn:jboss:domain:messaging:1.1">
            <hornetq-server>
                <persistence-enabled>true</persistence-enabled>
                <journal-file-size>102400</journal-file-size>
                <journal-min-files>2</journal-min-files>
                <security-enabled>false</security-enabled> 

Now you can also use QueueConnection qcon = qconFactory.createQueueConnection();

That's all

4 comments:

  1. Hi there, your information is excelent ! Thank you a lot.

    You need extra config to maket hornetQ going that is missed in your text.

    This are
    Is needed at



    Regards

    ReplyDelete
    Replies
    1. Hi,

      can you escape your xml so I know what I missed.

      thanks

      Delete
  2. Thanks for a helpful post.

    I need to connect to a topic that sits on another server. I am battling to find an example that shows where I would put the remote server IP and port etc. Can you possibly assist? Thanks in advance. T

    ReplyDelete
    Replies
    1. Hi,

      You need to do this on the client and in the JNDI lookup.
      env.put(Context.PROVIDER_URL, jbossUrl);

      thanks

      Delete