Saturday, February 18, 2017

TomEE JMS

Why I wrote this up?

When I was trying to hook up JMS with TomEE-Plus, I looked for on-line resources. There are multiple tutorials on how to do this, but not all information could be found in one page. So this tutorial is the result of gleaning from various sources. Hope you find it useful. I am not big on analysis. So let's go straight into coding.

Tested this on TomEE-Plus-1.7.4; does not work with Tomee 7 or other servers

First Configure conf/tomee.xml as follows

<tomee>
  <!-- see http://tomee.apache.org/containers-and-resources.html -->

  <!-- activate next line to be able to deploy applications in apps -->

  <!-- <Deployments dir="apps" /> -->

<Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig =  broker:(tcp://localhost:61616)
        ServerUrl       =  tcp://localhost:61616
    </Resource>

    <Resource id="MyJmsConnectionFactory" type="javax.jms.ConnectionFactory">
        ResourceAdapter = MyJmsResourceAdapter
    </Resource>

    <Container id="MyJmsMdbContainer" ctype="MESSAGE">
        ResourceAdapter = MyJmsResourceAdapter
    </Container>

    <Resource id="barQueue" type="javax.jms.Queue"/>
    <Resource id="fooTopic" type="javax.jms.Topic"/>
</tomee>

Create a servlet thus

package com.apache.jms;


import java.io.IOException;

import javax.annotation.Resource;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name="mytest", urlPatterns={"/myurl"}) 
 public class MyJmsServlet extends HttpServlet {
  
     //@Resource(name = "fooTopic")
     static private Topic fooTopic;
  
     //@Resource(name = "barQueue")
     static private Queue barQueue;
  
     //@Resource (name="MyJmsConnectionFactory" , type = ConnectionFactory.class)
     static private ConnectionFactory connectionFactory;
  
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //...
  try {
    InitialContext ctx = new InitialContext();
    connectionFactory = (ConnectionFactory) ctx.lookup("java:openejb/Resource/MyJmsConnectionFactory");
    barQueue = (Queue) ctx.lookup("java:openejb/Resource/barQueue");
    fooTopic = (Topic) ctx.lookup("java:openejb/Resource/fooTopic");
         Connection connection = connectionFactory.createConnection();
         connection.start();
  
         // Create a Session
         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  
         // Create a MessageProducer from the Session to the Topic or Queue
         MessageProducer producer = session.createProducer(barQueue);
         producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  
         // Create a message
         TextMessage message = session.createTextMessage("Hello World!");
  
         // Tell the producer to send the message
         producer.send(message);
  
         //...
     } catch (Exception e) {
      e.printStackTrace();
     }
     }
     
     public static void main(String [] args) {
       try {
           Connection connection = connectionFactory.createConnection();
           connection.start();
    
           // Create a Session
           Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
           // Create a MessageProducer from the Session to the Topic or Queue
           MessageProducer producer = session.createProducer(fooTopic);
           producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    
           // Create a message
           TextMessage message = session.createTextMessage("Hello World!");
    
           // Tell the producer to send the message
           producer.send(message);
    
           //...
       } catch (Exception e) {
        e.printStackTrace();
       }
     }
}

Create a client thus

package com.apache.jms;

import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.InitialContext;

public class MyJmsClient {
   //@Resource(name = "fooTopic")
    static private Topic fooTopic;
 
    //@Resource(name = "barQueue")
    static private Queue barQueue;
 
    //@Resource (name="MyJmsConnectionFactory" , type = ConnectionFactory.class)
    static private ConnectionFactory connectionFactory;
    private static MessageConsumer consumer=null;
 public static void main(String [] args) {
     try {
      Properties props = new Properties();
//      props.put("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory");
      props.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory");
       
           props.put("java.naming.provider.url", "http://127.0.0.1:8080/tomee/ejb");
        props.put("java.naming.security.principal", "tomee");
        props.put("java.naming.security.credentials","tomee");
      InitialContext ctx = new InitialContext(props);
    connectionFactory = (ConnectionFactory) ctx.lookup("MyJmsConnectionFactory");
    barQueue = (Queue) ctx.lookup("barQueue");
    fooTopic = (Topic) ctx.lookup("fooTopic");
         Connection connection = connectionFactory.createConnection();
  
        Session session = connection.createSession(
              false, 
              Session.AUTO_ACKNOWLEDGE);
   consumer = session.createConsumer(barQueue);
   connection.start();
   while (true) {
       Message m = consumer.receive(1); 
       if (m != null) { 
           if (m instanceof TextMessage) { 
               TextMessage message = (TextMessage) m; 
               System.out.println("Reading message: " + message.getText()); 
           } else { 
               break; 
           } 
       }
   }
     } catch (Exception e) {
      e.printStackTrace();
     }
   }
}

Run the main method of the client; make sure it is listening for messages; and pass this to the JVM -DResource/javax.jms.ConnectionFactory=connectionfactory:org.apache.activemq.ActiveMQConnectionFactory:tcp://localhost:61616

For example:

java -cp ./activemq-all-5.14.3.jar:openejb-client-7.0.2.jar:concurrent-1.3.3.jar:javax.ejb.jar:. -DResource/javax.jms.ConnectionFactory=connectionfactory:org.apache.activemq.ActiveMQConnectionFactory:tcp://172.20.0.218:61616 MyJmsClient topic

Deploy the servlet on TomEE and invoke it as http://localhost:8080/myurl

You should see the following message

Reading message: Hello World!

Required Jars:

  • activemq-all-5.14.3.jar
  • openejb-client-7.0.2.jar
  • concurrent-1.3.3.jar

  • Wednesday, February 15, 2017

    Active MQ Stand Alone

    Download apache-activemq-5.14.3.zip

    Unzip it

    set JAVA_HOME and go to the bin directory and type "activemq start"

    Create a Sender Thus

    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import org.apache.activemq.ActiveMQConnection;
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    public class Sender {
    
    private ConnectionFactory factory = null;
    private Connection connection = null;
    private Session session = null;
    private Destination destination = null;
    private MessageProducer producer = null;
    
    public Sender() {
    
    }
    
    public void sendMessage() {
    
    try {
    factory = new ActiveMQConnectionFactory(
    ActiveMQConnection.DEFAULT_BROKER_URL);
    connection = factory.createConnection();
    connection.start();
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    destination = session.createQueue("SAMPLEQUEUE");
    producer = session.createProducer(destination);
    TextMessage message = session.createTextMessage();
    message.setText("Hello ...This is a sample message..sending from FirstClient");
    producer.send(message);
    System.out.println("Sent: " + message.getText());
    
    } catch (JMSException e) {
    e.printStackTrace();
    }
    }
    
    public static void main(String[] args) {
    Sender sender = new Sender();
    sender.sendMessage();
    }
    
    }
    

    Create a receiver thus

    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import org.apache.activemq.ActiveMQConnection;
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    public class Receiver {
    private ConnectionFactory factory = null;
    private Connection connection = null;
    private Session session = null;
    private Destination destination = null;
    private MessageConsumer consumer = null;
    
    public Receiver() {
    
    }
    
    public void receiveMessage() {
    try {
    factory = new ActiveMQConnectionFactory(
    ActiveMQConnection.DEFAULT_BROKER_URL);
    connection = factory.createConnection();
    connection = factory.createConnection();
    connection.start();
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    destination = session.createQueue("SAMPLEQUEUE");
    consumer = session.createConsumer(destination);
    Message message = consumer.receive();
    
    if (message instanceof TextMessage) {
    TextMessage text = (TextMessage) message;
    System.out.println("Message is : " + text.getText());
    }
    } catch (JMSException e) {
    e.printStackTrace();
    }
    }
    
    public static void main(String[] args) {
    Receiver receiver = new Receiver();
    receiver.receiveMessage();
    }
    }
    
    

    when compiling the files use the following class path

    C:\jms>"c:\Program Files\java\jdk1.8.0_101\bin\javac.exe" -cp apache-activemq-5.1
    4.3\activemq-all-5.14.3.jar;. Sender.java
    

    When running use the same class path


    Windows invokation of Client

    C:\jms>"c:\Program Files\Java\jdk1.8.0_101\bin\java.exe" 
    -cp apache-activemq-5.14.3\activemq-all-5.14.3.jar;.;bak\openejb-client.jar;bak\javax.ejb.jar -DResource/javax.jms.ConnectionFactory=connectionfactory:org.apache.activemq.ActiveMQConnectionFactory:tcp://localhost:61616 MyJmsClient