Monday, June 24, 2013

MDB Using Jboss 7

Jboss 7 architecture is completely changed compared to the previous versions. Due to this, there is a change in configuration of queues, connection factories, security etc. Here, we are not going to see how we create MDB, rather we will look at how to configure to work in Jboss7 and how to create a standalone client to send a message to Queue on Jboss7.
Jboss7 has been fully modulated, we treat each and every component of jboss7 as separate module. This has to be done in standalone.xml file. By default, we get different versions of standalone files like standalone, standalone-full etc. I prefer to use standalone.xml and add modules as required.
To enable messaging we need to add the following lines to standalone file
  • In <extensions> tag, add
<extension module="org.jboss.as.messaging"/>
  • Add sub-system in <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>

        <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>
            </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="MyQueue">
                <entry name="queue/MyQueue"/>
                <entry name="java:jboss/exported/jms/queue/MyQueue"/>
            </jms-queue>
        </jms-destinations>
    </hornetq-server>
</subsystem>
  • This creates a queue named MyQueue. Now i can deploy a MDB listening to the queue "MyQueue". Listener class is as follows.
@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MyQueue") }, mappedName = "MyQueue")
public class QueueListener implements MessageListener {

 private static final Logger logger = Logger.getLogger(QueueListener.class);

 /**
  * @see MessageListener#onMessage(Message)
  */
 public void onMessage(Message message) {
  logger.debug("Inside onMessage");
  try {
   if (message instanceof TextMessage) {

    TextMessage msg = (TextMessage) message;
    logger.info("Message : " + msg.getText());
   }
  } catch (Exception e) {
   logger.error("Exception while processing the message ", e);
  }

 }
}
  • After deploying, start the Jboss7, you will find log saying QueueListener is listening using hornetq-ra resource adapter. Now, it's time to send a message to the Queue. Here is the client which can send the message to the Queue.
public class MDBClient {
 public static void main(String... strings) {
  try {
   final Properties props = new Properties();
   props.put(Context.INITIAL_CONTEXT_FACTORY,     "org.jboss.naming.remote.client.InitialContextFactory");
   props.put(Context.PROVIDER_URL, "remote://localhost:4447");
   props.put(Context.SECURITY_PRINCIPAL, "sample");
   props.put(Context.SECURITY_CREDENTIALS, "sample123");

   InitialContext context = new InitialContext(props);
   QueueConnectionFactory factory = (QueueConnectionFactory) context     .lookup("jms/RemoteConnectionFactory");
   Queue queue = (Queue) context.lookup("jms/queue/MyQueue");
   QueueConnection cnn = factory.createQueueConnection("sample",     "sample123");
   QueueSession session = cnn.createQueueSession(false,     QueueSession.AUTO_ACKNOWLEDGE);
   QueueSender sender = session.createSender(queue);
   TextMessage message = session.createTextMessage();
   message.setText("Text Message");
   sender.send(message);
   context.close();
   cnn.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
  • Run the above code, which sends the message to Jms Queue "MyQueue". Add jboss-client.jar ($JBOSS_HOME/bin/client/jboss-client.jar) to classpath to get it running.
Points to remember
  1. Remote JNDI : A new entry added for RemoteConnectionFactory (java:jboss/exported/jms/RemoteConnectionFactory) to expose it so that it can be called looked up from remote. Same is the case for the queue (java:jboss/exported/jms/queue/MyQueue)
  2. Security: Credentials to be passed to the Context and While creating connection to connect to Queue. The credentials must be of user who belongs to group (guest). User can be setup by using adduser script in $JBOSS_HOME/bin.
  3. Off the Secutiry: We can off the security by adding <security-enabled>false</security-enabled> to the hornetq-server element
  4. Jboss-Client: jboss-client.jar which is added to Standalone client classpath.