JBoss JMS Topic example

The following article shows how to create a simple JMS Topic using WildFly and older versions of JBoss application server.

Creating a JMS Topic with WildFly

If you want to create a new Topic, the command to be executed from the CLI is the following one:

[standalone@localhost:9990 /] jms-topic add --topic-address=jms.topic.DemoTopic --entries=java:/jms/topic/demoTopic

The following topic will be added in your XML configuration:

<jms-topic name="jms.topic.DemoTopic" entries="java:/jms/topic/demoTopic"/>

On the other hand, if you are using Domain mode, you should specify the profile as argument:

[domain@localhost:9990 /] jms-topic add --profile=full-ha --topic-address=jms.topic.DemoTopic --entries=java:/jms/topic/demoTopic

To see an example application which uses JMS to send messages, check this tutorial: JBoss JMS configuration

Creating a Deployable Topic

JMS destinations can be also be created on the fly by dropping a *-jms.xml file in the deployments folder of your standalone server or packaging it along with your application. Here’s an example of a JMS Queue and a JMS Topic:

<messaging-deployment xmlns="urn:jboss:messaging-activemq-deployment:1.0">
    <server>
        <jms-destinations>
            <jms-queue name="ExampleQueue">
                <entry name="java:/jms/queue/ExampleQueue"/>
                <durable>true</durable>
            </jms-queue>
            <jms-topic name="ExampleTopic">
                <entry name="java:/jms/topic/ExampleTopic"/>
            </jms-topic>
        </jms-destinations>
    </server>
</messaging-deployment>

Creating a JMS Topic with JBoss 5

At first you need to deploy a JMS Topic to JBoss. Create a file ending with -service.xml in the deploy folder of JBoss.

Case 1: JBoss Messaging
If you are running JBoss 5, which ships with JBoss messaging you can use the following descriptor:

<mbean code="org.jboss.jms.server.destination.TopicService"
      name="jboss.messaging.destination:service=Topic,name=topicA"
      xmbean-dd="xmdesc/Topic-xmbean.xml">
   <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
   <depends>jboss.messaging:service=PostOffice</depends>
</mbean>

Case 2: JBoss MQ
If you using JBoss older JMS provider, the configuration file is the following:

<mbean code="org.jboss.mq.server.jmx.Topic"
     name="jboss.mq.destination:service=Queue,name=topicA">
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>

Example Code:

package com.sample;


import java.util.Properties;
import java.util.Scanner;

import javax.jms.*;
import javax.naming.Context;
 

public class TopicExample implements MessageListener  
{
   
   public void example() throws Exception
   {
      String destinationName = "topic/topicA";
      
      Context ic = null;
      ConnectionFactory cf = null;
      Connection connection =  null;

      try
      {         
         ic = getInitialContext();
         
         cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
         Topic topic = (Topic)ic.lookup(destinationName);
         
         connection = cf.createConnection();
         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer publisher = session.createProducer(topic);
         MessageConsumer subscriber = session.createConsumer(topic);
         
         subscriber.setMessageListener(this);
         connection.start();
         
         TextMessage message = session.createTextMessage("Hello!");
         publisher.send(message);
               
          Scanner keyIn = new Scanner(System.in); 
          
          System.out.print("JMS Server listening. Type a Key + CR to exit\n");
         keyIn.next();
               
      }
      finally
      {         
         if(ic != null)
         {
            try
            {
               ic.close();
            }
            catch(Exception e)
            {
               throw e;
            }
         }
         
         // ALWAYS close your connection in a finally block to avoid leaks.
         // Closing connection also takes care of closing its related objects e.g. sessions.
         closeConnection(connection);
      }
   }
   public synchronized void onMessage(Message message)
   {
      TextMessage text = (TextMessage)message;
      String strMessage = null;
    try {
        strMessage = text.getText();
    } catch (JMSException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
      System.out.println("Message received: "+strMessage);
   }

   private void closeConnection(Connection con)
   {      
      try
      {
         if (con != null)
         {
            con.close();
         }         
      }
      catch(JMSException jmse)
      {
          System.out.println("Could not close connection " + con +" exception was " + jmse);
      }
   }
      
   protected boolean isQueueExample()
   {
      return true;
   }
   
   public static void main(String[] args) throws Exception
   {
      new TopicExample().example();
   }
   public static Context getInitialContext( )
    throws javax.naming.NamingException {

        Properties p = new Properties( );
        p.put(Context.INITIAL_CONTEXT_FACTORY,
                "org.jnp.interfaces.NamingContextFactory");
        p.put(Context.URL_PKG_PREFIXES,
        " org.jboss.naming:org.jnp.interfaces");
        p.put(Context.PROVIDER_URL, "jnp://localhost:1099");
        return new javax.naming.InitialContext(p);
    }  
}

Found the article helpful? if so please follow us on Socials