Pages

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

11 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
    2. My code is exactly as the example... when I run the application with localhost, all works fine. But, when I try running the server on other machine and changing the jbossURL with the IP, it gives me the error:

      Exception in thread "main" javax.naming.NamingException: Failed to create remoting connection [Root exception is java.lang.RuntimeException: Operation failed with status WAITING]
      at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
      at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:121)
      at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
      at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
      at javax.naming.InitialContext.init(Unknown Source)
      at javax.naming.InitialContext.(Unknown Source)
      at Main.getInitialContext(Main.java:29)
      at Main.main(Main.java:33)
      Caused by: java.lang.RuntimeException: Operation failed with status WAITING
      at org.jboss.naming.remote.protocol.IoFutureHelper.get(IoFutureHelper.java:89)
      at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:56)
      at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:166)
      at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:139)
      at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:104)
      ... 6 more



      Any idea?

      Delete
    3. Can you try to change the jboss.bind.address from 127.0.0.1 to 0.0.0.0

      Delete
    4. Hi, may I ask If where can I find the jboss.bind.address? Thanks!

      Delete
  3. You are great man, this helped me a lot.

    ReplyDelete
  4. Hi, I followed these steps, but i encounter following exceptions..why is that?

    Exception in thread "main" javax.naming.NameNotFoundException: jms/RemoteConnectionFactory -- service jboss.naming.context.java.jboss.exported.jms.RemoteConnectionFactory
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:97)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:178)
    at org.jboss.naming.remote.protocol.v1.Protocol$1.handleServerMessage(Protocol.java:127)
    at org.jboss.naming.remote.protocol.v1.RemoteNamingServerV1$MessageReciever$1.run(RemoteNamingServerV1.java:73)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:662)

    ReplyDelete
    Replies
    1. Hi,

      is the messaging part loaded and do you see this entry java:jboss/exported/jms/RemoteConnectionFactory in the hornetq configuration.

      Thanks

      Delete
  5. Hi ,

    I am getting the below error can u help

    Oct 02, 2015 11:41:58 AM org.xnio.Xnio
    INFO: XNIO Version 3.0.3.GA
    Oct 02, 2015 11:41:58 AM org.xnio.nio.NioXnio
    INFO: XNIO NIO Implementation Version 3.0.3.GA
    Oct 02, 2015 11:41:58 AM org.jboss.remoting3.EndpointImpl
    INFO: JBoss Remoting version 3.2.3.GA
    Oct 02, 2015 11:41:58 AM org.jboss.remoting3.remote.RemoteConnection handleException
    ERROR: JBREM000200: Remote connection failed: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed
    Exception in thread "main" javax.naming.NamingException: Failed to create remoting connection [Root exception is java.lang.RuntimeException: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed]
    at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
    at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:121)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.init(InitialContext.java:242)
    at javax.naming.InitialContext.(InitialContext.java:216)
    at com.jms.jboss.QueueSend.getInitialContext(QueueSend.java:29)
    at com.jms.jboss.QueueSend.main(QueueSend.java:33)
    Caused by: java.lang.RuntimeException: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed
    at org.jboss.naming.remote.protocol.IoFutureHelper.get(IoFutureHelper.java:87)
    at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:56)
    at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:166)
    at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:139)
    at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:104)
    ... 6 more
    Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed
    at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:365)
    at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:214)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
    at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)
    at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
    at org.xnio.nio.NioHandle.run(NioHandle.java:90)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:184)
    at ...asynchronous invocation...(Unknown Source)
    at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:270)
    at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:251)
    at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:349)
    at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:333)
    at org.jboss.naming.remote.client.EndpointCache$EndpointWrapper.connect(EndpointCache.java:105)
    at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:55)
    ... 9 more

    ReplyDelete