JAVA EE 7 @Startup @Singleton RabbitMQ Listener Service on TomEE 7

Introduction

When you start to develop a web application you usually expect that each action that happens on the server side is triggered by its user. But what if you actually want to start something that just runs in the background without the need of being triggered? Like with a jar file when you just use the main method and everything starts from there. Java EE solves that with a pair of annotations that can start a service along with the start of the server. These two are: @Singleton and @Startup. In this article we are going to use them to start a RabbitMQ listener. During the start of the server we run the RabbitMQ listener that will be receiving messages that are sent to it. What we can do with them? For sure there are lot of ideas but for an example we can simply print them out! Instead of using heavy tools such as Weblogic we are going to do that with TomEE, which is basicaly Tomcat with extra Java EE functions (http://tomee.apache.org/)

Versioning

  • TomEE 7.0.2
  • Eclipse Version: Oxygen.2 Release (4.7.2)
  • Java 1.8.0_131
  • rabbitmq-server-3.7.2

Prerequisite

You need a working RabbitMQ server, preferably installed on your own PC. All you have to do is to download and install it from here: https://www.rabbitmq.com/

Setting up the project

  1. From the File menu → New → Dynamic Web Project
  2. Project Name: JavaEERabbitMQ
  3. Target runtime: Apache Tomcat v8.5 (this is how TomEE is displayed, add one if needed)
  4. Next... Next...
  5. Tick „Generate web.xml deployment descriptor” 
  6. Finish

Converting to maven

From the Project Explorer view right click on the Project → configure → Convert to Maven Project →  Finish

Adding dependencies

   <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>5.1.2</version>
   </dependency>

Create RestApiServlet class

  1. Create new class Name: RecevierControl
  2. Package: com.blogspot.itsystemengineer 
  3. Paste its content

RecevierControl.java

package com.blogspot.itsystemengineer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

@Startup
@Singleton
public class RecevierControl {
 private final static String QUEUE_NAME = "hello";

 @PostConstruct
 void init() throws IOException, TimeoutException {
  ConnectionFactory factory = new ConnectionFactory();
  factory.setHost("localhost");
  Connection connection = null;
  connection = factory.newConnection();
  Channel channel = null;
  channel = connection.createChannel();
  channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  System.out.println(" [*] Waiting for messages.");
  Consumer consumer = new DefaultConsumer(channel) {
   @Override
   public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
     byte[] body) throws IOException {
    String message = new String(body, "UTF-8");
    System.out.println(" [x] Received '" + message + "'");
   }
  };
  channel.basicConsume(QUEUE_NAME, true, consumer);
 }
}
You can just simply send a message directly from the RabbitMQ management console (by firstly enabling it: https://www.rabbitmq.com/management.html), but it is easier if you just use this Java class to send it over to the queue. Create a new Java class, call it Sender and paste the following content:

Sender.java

package com.blogspot.itsystemengineer;

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;

public class Sender {
 private final static String QUEUE_NAME = "hello";

 public static void main(String[] argv) throws java.io.IOException, TimeoutException {
  ConnectionFactory factory = new ConnectionFactory();
  factory.setHost("localhost");
  Connection connection = factory.newConnection();
  Channel channel = connection.createChannel();
  channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  String message = "You did it!";
  channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
  System.out.println(" [x] Sent '" + message + "'");
  channel.close();
  connection.close();
 }
}

Running

Now Start the TomEE server with the deployed web application. Once it is running, simply run the Sender class (it contains the main method). Everything should work by that time. Enjoy!

Comments

Post a Comment