Thursday, August 6, 2015

Establishing remote connection to JBoss messaging service

Just done some test drive on establishing a remote connection to the JBoss messaging service. As of this writing, I'm working on JBoss EAP 6.3.0. Assume I have the connection factory configuration being done in following way:
   <jms-connection-factories>
      <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>
   <jms-connection-factories>

   ...
   ...

   <jms-destinations>
      <jms-topic name="testTopic">
         <entry name="topic/test"/>
         <entry name="java:jboss/exported/jms/topic/test"/>
      </jms-topic>

      ...
   </jms-destinations>
Then the following piece is the code trying to achieve the mission:
   ...

   Properties prop = new Properties();
   prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
   prop.put(Context.PROVIDER_URL, "remote://localhost:4447");
   prop.put(Context.SECURITY_PRINCIPAL, "huahsin68");
   prop.put(Context.SECURITY_CREDENTIALS, "abcdef.1");

   ctx = new InitialContext(prop);
   TopicConnectionFactory topicFac = (TopicConnectionFactory) ctx.lookup("/RemoteConnectionFactory");
   TopicConnection topicConn = topicFac.createTopicConnection();
   TopicSession topicSess = topicConn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
   Topic topic = (Topic) ctx.lookup("/topic/test");
   topicConn.start();

   ...
There are a couple of mistakes here. First, the lookup(...) method will fail on connection factory initialization, RemoteConnectionFactory was unable to find. This error would be seen as:

Exception in thread "main" javax.naming.NameNotFoundException: RemoteConnectionFactory -- service jboss.naming.context.java.jboss.exported.RemoteConnectionFactory

Second is the authentication with SECURITY_PRINCIPAL and SECURITY_CREDENTIALS is not working during the context initialization. The authentication need to be done during the connection is first created, which is on createTopicConnection() method call.

Third mistake would be the /topic/test was unable to initialize too. The error is same as the first mistake. The fixes on the lookup(...) thing should prefix with jms. This following piece would be the complete set for the fixes:
   ...

   Properties prop = new Properties();
   prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
   prop.put(Context.PROVIDER_URL, "remote://localhost:4447");

   ctx = new InitialContext(prop);
   TopicConnectionFactory topicFac = (TopicConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
   TopicConnection topicConn = topicFac.createTopicConnection("huahsin68", "abcdef.1");
   TopicSession topicSess = topicConn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
   Topic topic = (Topic) ctx.lookup("jms/topic/test");
   topicConn.start();

   ...
Wonder why jms should put in the prefix? JBoss documentation did mention this:
Keep in mind that any jms-queue or jms-topic which needs to be accessed by a remote client needs to have an entry in the "java:jboss/exported" namespace. As with connection factories, if a jms-queue or jms-topic has an entry bound in the "java:jboss/exported" namespace a remote client would look it up using the text after "java:jboss/exported".

No comments: