JMS Queue: Configuration and Setup Simplified

on Java, JavaScript, Message Queue, Tutorials • May 20th, 2022 • Write for Hevo

JMS Queue- Featured Image

Java Messaging Service (JMS) is a popular API standard for application-to-application messaging. It offers a rich set of message delivery semantics and a simple yet flexible API for incorporating messaging into applications. What is more, JMS API is easy to learn and implement once you have a working knowledge of the Java language.

JMS Queue provides a virtual channel to exchange messages in a Point-to-Point Messaging Model. It decouples consumers from producers to provide asynchronous communication and uses load-balancing techniques to distribute messages evenly among consumers. Due to its asynchronous abilities coupled with reliable message delivery, JMS is used by Java developers in Enterprise Application Integration, Business to Business (B2B) projects, and distributed computing in general.

Today, we are discussing the main characteristics of JMS Queue, its architecture, benefits, and use cases. We’ll show you steps to create your own JMS Queue in as easy as 10 steps and also talk about sample applications of JMS Queue like deploying Queue Sender, Asynchronous Queue Receiver, and multiple consumers in a JMS Queue.

Table of Contents

What Is Message-Oriented Middleware (MOM)?

Message Oriented Middleware: JMS Queue | Hevo Data
Image Source: Oreilly Media

Application-to-application communication hasn’t always been the same. Traditionally, an application would perform an action and in turn trigger a number of resource requests. Upon request, another application would execute a trailing action and answer the queries. Such communication is referred to as Synchronous Communication. It requires two or more parties to talk or exchange messages at the same time.

But recent developments in application communication have led to Asynchronous Messaging (loosely coupled applications), a communication mode where two applications can communicate without the requirement of being “present” at the same time. Asynchronous Messaging provides convenience and flexibility for both the message consumer and the message producer. It provides application users with remedies to reduce system bottlenecks, and increase end-user productivity and overall system scalability.

In business, asynchronous communication systems between applications are generally referred to as enterprise messaging systems, or Message-Oriented Middleware (MOM). JMS is one example of MOM that we’ll discuss in this blog. MOM transmits messages from one application to another across a network and ensures that messages are properly distributed. This increases the overall scalability and throughput of a system while accelerating end-user productivity.

What Is Java Message Service (JMS)?

JMS Overview: JMS Queue | Hevo Data
Image Source: Oracle Docs

For Java applications, asynchronous messaging service combined with portability, reliability, scalability, and transactional support fabricates into Java Message Service (JMS). At its core, Java Message Service is a Java API that allows applications to create, send, receive, and read distributed enterprise messages. It is analogous to Java Database Connectivity (JDBC) API in that application developers can reuse the same Java API to access and connect to different application systems.

Java Message Service is a robust API to easily and efficiently support a wide range of enterprise messaging products. It provides a single platform for Java Client Applications and Java Middle-Tier Services yoked with a common set of interfaces and semantics. This engineering enables Java programs to connect with messaging implementations built in other languages as well.

Using Java API is simple and requires minimal learning. JMS API has very few concepts that a programmer needs to learn to be able to take advantage of JMS Queue Systems. Aside from that, don’t be misled by JMS API’s simplicity; it also has enough functionality to handle advanced messaging systems.

Java Message Service Architecture

Java Message Service application consists of the following components:

  1. JMS Clients: Java components or applications use the JMS API and JMS Provider to send and receive messages.
  2. Non-JMS Clients: Programs that use a message system’s native client API instead of JMS.
  3. Messages: Package of business data that is sent by the sender (producer application) to the receiver (consumer application). The JMS Queue offers six message interface types: TextMessage, StreamMessage, MapMessage, ObjectMessage, and BytesMessage.
  4. JMS Provider: A Messaging System that implements the JMS API and other administrative and control functionality to provide connectivity to its MOM.
  5. Administered Objects: Preconfigured JMS objects developed by the administrator for the use of Java programs. These are of two types:
    1. ConnectionFactory – An object that a client uses to create a connection with a provider.  
    2. Destination – An object that a client uses to specify the destination and the source of messages.

Merging all the concepts and components from above, we get interaction as follows: 

JMS Architecture: JMS Queue | Hevo Data
Image Source: dev.cs.ovgu.de

Administrative Tools allow you to bind destinations and connection factories into a Java Naming and Directory Interface (JNDI) API namespace. A JMS Client then looks up the administered objects in the namespace and then establishes a logical connection to the same objects using the JMS Provider.

Simplify ETL Using Hevo’s No-Code Data Pipeline

Hevo Data, a Fully-managed Data Pipeline platform, can help you automate, simplify & enrich your data replication process in a few clicks. With Hevo’s wide variety of connectors and blazing-fast Data Pipelines, you can extract & load data from 100+ Data Sources straight into Data Warehouses, or any Databases. To further streamline and prepare your data for analysis, you can process and enrich raw granular data using Hevo’s robust & built-in Transformation Layer without writing a single line of code!

GET STARTED WITH HEVO FOR FREE

Hevo is the fastest, easiest, and most reliable data replication platform that will save your engineering bandwidth and time multifold. Try our 14-day full access free trial today to experience an entirely automated hassle-free Data Replication!

When Can You Use the JMS API?

Your decision to choose a messaging API like JMS over a tightly coupled API like Remote Procedure Call (RPC) is right when: 

  • You want your components not to depend on information about other components’ interfaces.
  • You want your applications to run whether their components are up and running simultaneously.
  • Likewise, you want an application business model that allows a component to send information to another and to continue to operate without receiving an immediate response.

Benefits of Java Message Service API (JMS)

  • Easy to Learn and Use: JMS APIs are quick to learn and simple to use for developers.
  • Asynchronous Processing: JMS delivers asynchronous messaging between applications. Once a message is sent, the JMS Client can move on to other tasks. It doesn’t have to wait for a response. 
  • High Availability: JMS provides high availability capabilities to keep business applications in continuous operation with uninterrupted service.
  • Reliable Messaging: JMS provides guaranteed delivery, which ensures that intended consumers will eventually receive a message even if a partial failure occurs.
  • Store-and-Forward: JMS writes incoming messages to a persistent store if the intended consumers are not currently available.

The Java Message Service Programming Model

In a broad sense, a JMS application is one or more JMS Clients that exchange messages. Non-JMS Clients can be involved in the application, but they will utilize the JMS provider’s native API instead of JMS. Between these applications are self-contained packages of business data that get exchanged, and each JMS message comprises the following components:

  • Header: The header declares the attributes of a message and provides information for routing.
  • Properties (optional): The properties segment contains additional metadata about the message that is set by the application developer or JMS Provider. Each message can have three different properties:
    • Application-Specific Properties: Specify application-specific header fields to a message.
    • Standard Properties: Standard and optional properties specified by the JMS.
    • Provider-Specific Properties: Specify provider-specific properties for integrating a JMS client with a JMS provider native client.
  • Body (optional): The body contains the actual data to communicate. 

The JMS defines six types of messages that a JMS Provider must support:

  1. Message: The simplest type of message that lacks a body.
  2. StreamMessage: A message whose body carries a stream of primitive Java types.
  3. MapMessage: A message whose body contains a set of name-value pairs. The order of entries is not defined.
  4. TextMessage: A message whose body carries java.lang.String.
  5. ObjectMessage: A message that carries a serializable Java object.
  6. BytesMessage: A message whose body contains an array of primitive bytes.

Java Message Service: Message Styles

JMS supports two styles of messaging: 

JMS Point-to-Point (PTP) Messaging Model Using JMS Queues

JMS Point-to-Point (PTP) Messaging: JMS Queue | Hevo Data
Image Source: Upsolver

Point-to-Point (PTP) Messaging Model allows Java programs to send and receive messages via virtual channels known as JMS Queues. In this model, the applications that produce messages are called “senders” and the applications that receive messages are called “consumers”. 

In the PTP Messaging Model, JMS Queue delivers one message to only one consumer application. There may be multiple consumers attached to the JMS Queue, but each message in the JMS Queue is only consumed by one receiver application to which it is addressed. From its beginning, PTP Messaging Model has been a pull-based model, where consumers have to request messages from the JMS Queue instead of receiving them automatically. 

JMS Point-to-Point Messaging Models support both synchronous “request/reply” messaging and asynchronous “fire and forget” messaging. Although PTP models don’t have any timing dependencies between the sender and the consumer, the connection between the sender and the consumer application tends to be more coupled.

The sender has to know how the message is going to be used and who is going to receive it, and the receiver can fetch the message regardless of whether it was running when the sender application sent it. Once it’s successfully received, the receiver acknowledges the successful processing of a message to the JMS Queue so that it can be removed from the JMS Queue.

JMQ Queue PTP also offers another feature called JMS Queue Browser that allows a JMS Client to view the contents of a JMS Queue prior to consuming the messages. Using JMS API you can browse the messages in the JMS Queue and display the header values for each message.

On a higher level, if we were to summarize everything, a JMS Queue Point-to-Point Messaging Model has the following characteristics:

  • Each message has only one consumer.
  • The sender and the receiver of a message have no timing dependencies, in other words, they are loosely coupled.
  • The receiver can fetch the message whether or not it was running when the client sent the message. Once received, the receiver acknowledges the successful processing of a message.

JMS Publish-and-Subscribe (Pub/Sub) Messaging Using Topics

JMS Publish-and-Subscribe (Pub/Sub) Messaging: JMS Queue | Hevo Data
Image Source: Data Driven Investor

Unlike the JMS Queue Model where each message is consumed by only one receiver, a Publish-and-Subscribe Messaging Model delivers one message to multiple subscribers. In JMS Publish-and-Subscribe Model, messages are published to a virtual channel called a Topic, and the exchange of messages happens between “publishers” (message producers) and “subscribers” (message consumers). Topics contain the message and additional details like publisher and subscriber information. 

Compared to JMS Queue Messaging Model, Publish-and-Subscribe can deliver messages to multiple subscribers automatically, without them having to request or poll messages. This is known as a push-based model where all subscribers subscribed to that topic will receive messages for further processing.

Another difference comes from the fact that the PTP Messaging Model requires the sender application to know the address of the receiver application. In Publish-and-Subscribe, the producer doesn’t need to know about the subscribers. This characteristic provides higher decoupling for Java applications and components.

What makes Hevo’s ETL Process Best-In-Class

Providing a high-quality ETL solution can be a difficult task if you have a large volume of data. Hevo’s automated, No-code platform empowers you with everything you need to have for a smooth data replication experience.

Check out what makes Hevo amazing:

  • Fully Managed: Hevo requires no management and maintenance as it is a fully automated platform.
  • Data Transformation: Hevo provides a simple interface to perfect, modify, and enrich the data you want to transfer.
  • Faster Insight Generation: Hevo offers near real-time data replication so you have access to real-time insight generation and faster decision making. 
  • Schema Management: Hevo can automatically detect the schema of the incoming data and map it to the destination schema.
  • Scalable Infrastructure: Hevo has in-built integrations for 100+ sources (with 40+ free sources) that can help you scale your data infrastructure as required.
  • Live Support: Hevo team is available round the clock to extend exceptional support to its customers through chat, email, and support calls.
Sign up here for a 14-day free trial!

Steps to Create a JMS Queue

A JMS Queue is a point-to-point destination type for a JMS Server. Once you have configured your JMS Server, you can create one or more JMS Queues for your JMS Server. Provided here are the steps to create one:

Step 1: Expand JMS > Servers and select a JMS Server instance.

Step 2: Select the Destination node. On the right pane, you’ll see the JMS Destinations table showing all the JMS Queues.

Step 3: Click on Configure a new JMS Queue. The tabs for configuring a new JMS Queue will be displayed in the dialog box.

Step 4: Under the Configuration General tab, define the Queue’s general configuration attributes like:

  • Name of the JMS Queue destination.
  • JNDI name.
  • Specify if the JNDI name is to be replicated across the cluster.
  • Set whether the JMS Queue should support persistent messaging.
  • If you’re creating Queues using JMS, choose an existing template.
  • Pick from a list of existing destination keys to determine the sort order of messages as they arrive in the Queue.

Step 5: Click Create to establish a JMS Queue instance with the name you entered in the Name field. On the left pane’s Destination node, you’ll see the new instance added.

Step 6: Define the following higher and lower message/byte thresholds and maximum quota characteristics for the JMS Queue on the Configuration Thresholds & Quotas tab:

  • Maximum bytes or message quota for your JMS Queue.
  • The upper threshold value and the lower threshold value to trigger events based on the number of bytes or messages stored in the JMS Queue.
  • Enable/disable bytes or messages paging.
  • Maximum acceptable size of a message.

Step 7: Set the message attributes that a message producer can override from the Configuration Overrides tab, such as priority, time-to-live, time-to-deliver, and delivery mode.

Step 8: Define the message redelivery attributes on the Configuration Redelivery tab. This includes redelivery delay override, redelivery limit, and error destination.

Step 9: Set the message expiration policy on the Configuration Expiration Policy tab.

Step 10: Click Apply to save your changes.

JMS Queue Sample Applications

There are four sample programs in this section.

Simple JMS Queue Application

Here’s a simple JMS Queue application that sends and receives text messages using a point-to-point connection, i.e., using JMS Queues. The sample application serves as both a sender (sending the message to the Queue) and a receiver in this example (receiving the same message from the Queue).

import javax.jms.*;

public class HelloMsg {
   public static void main(String argv[]) throws Exception {
      // The producer and consumer need to get a connection factory and use it to set up
      // a connection and a session
      QueueConnectionFactory connFactory = new com.sun.messaging.QueueConnectionFactory();
      QueueConnection conn = connFactory.createQueueConnection();
      // This session is not transacted, and it uses automatic message acknowledgement
      QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
      Queue q = new com.sun.messaging.Queue("world");
      // Sender
      QueueSender sender = session.createSender(q);
      // Text message
      TextMessage msg = session.createTextMessage();
      msg.setText("Hello there!");
      System.out.println("Sending the message: "+msg.getText());
      sender.send(msg);
      // Receiver
      QueueReceiver receiver = session.createReceiver(q);
      conn.start();
      Message m = receiver.receive();
      if(m instanceof TextMessage) {
         TextMessage txt = (TextMessage) m;
         System.out.println("Message Received: "+txt.getText());
      }
      session.close();
      conn.close();
   }
}

If you would like to experiment with the sample JMS Queue application, you can do so by:

  • Copying the HelloMsg class and saving it in a new file, HelloMsg.java.
  • Compiling HelloMsg.java using javac -classpath <MQ_INSTALL_DIR>/lib/jms.jar{;|:}<MQ_INSTALL_DIR>/lib/img.jar HelloMsg.java.
  • Running HelloMsg as follows java -cp <MQ_INSTALL_DIR>/lib/jms.jar{;|:};<MQ_INSTALL_DIR>/lib/img.jar HelloMsg HelloMsg.

When you run the code, you should get the following output:

Sending the message: Hello there!
Message Received: Hello there!

JMS gives you options to build a unique setup by configuring the JMS source and receiver independently. We discuss two more sample programs to configure a JMS Sender and Asynchronous Queue Receiver. 

JMS Queue Sender

To configure a JMS Queue Sender, you can execute the following code and deploy your sender application.

package pointToPoint;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.QueueSender;
import javax.jms.DeliveryMode;
import javax.jms.QueueSession;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
                                                                           
public class Sender
{
    public static void main(String[] args) throws Exception
    {
    |   // get the initial context
    |   InitialContext ctx = new InitialContext();
    |                                                                      
    |   // lookup the queue object
    |   Queue queue = (Queue) ctx.lookup("queue/queue0");
    |                                                                      
    |   // lookup the queue connection factory
    |   QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
    |       lookup("queue/connectionFactory");
    |                                                                      
    |   // create a queue connection
    |   QueueConnection queueConn = connFactory.createQueueConnection();
    |                                                                      
    |   // create a queue session
    |   QueueSession queueSession = queueConn.createQueueSession(false,
    |       Session.DUPS_OK_ACKNOWLEDGE);
    |                                                                      
    |   // create a queue sender
    |   QueueSender queueSender = queueSession.createSender(queue);
    |   queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    |                                                                      
    |   // create a simple message to say "Hello"
    |   TextMessage message = queueSession.createTextMessage("Hello");
    |                                                                      
    |   // send the message
    |   queueSender.send(message);
    |                                                                      
    |   // print what we did
    |   System.out.println("sent: " + message.getText());
    |                                                                      
    |   // close the queue connection
    |   queueConn.close();
    }
}

This code uses a NON_PERSISTENT message delivery mode. In a non-persistent mode, a JMS Client can tolerate lost messages if the JMS Queue broker fails. In a persistent message delivery mode, a JMS Client cannot function if the messages are lost in transit.

Asynchronous Queue Receiver

Here’s another example of configuring an Asynchronous Queue Receiver. After receiving the message from the sender, an Asynchronous Queue Receiver does all message distribution tasks without requiring any involvement of the sender application. To deploy an Asynchronous Queue Receiver, you can use the following code:

package pointToPoint;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.MessageListener;
import javax.jms.JMSException;
import javax.jms.ExceptionListener;
import javax.jms.QueueSession;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
                                                                           
public class AsyncReceiver implements MessageListener, ExceptionListener
{
    public static void main(String[] args) throws Exception
    {
    |   // get the initial context
    |   InitialContext ctx = new InitialContext();
    |                                                                      
    |   // lookup the queue object
    |   Queue queue = (Queue) ctx.lookup("queue/queue0");
    |                                                                      
    |   // lookup the queue connection factory
    |   QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
    |       lookup("queue/connectionFactory");
    |                                                                      
    |   // create a queue connection
    |   QueueConnection queueConn = connFactory.createQueueConnection();
    |                                                                      
    |   // create a queue session
    |   QueueSession queueSession = queueConn.createQueueSession(false,
    |       Session.AUTO_ACKNOWLEDGE);
    |                                                                      
    |   // create a queue receiver
    |   QueueReceiver queueReceiver = queueSession.createReceiver(queue);
    |                                                                      
    |   // set an asynchronous message listener
    |   AsyncReceiver asyncReceiver = new AsyncReceiver();
    |   queueReceiver.setMessageListener(asyncReceiver);
    |                                                                      
    |   // set an asynchronous exception listener on the connection
    |   queueConn.setExceptionListener(asyncReceiver);
    |                                                                      
    |   // start the connection
    |   queueConn.start();
    |                                                                      
    |   // wait for messages
    |   System.out.print("waiting for messages");
    |   for (int i = 0; i < 10; i++) {
    |   |   Thread.sleep(1000);
    |   |   System.out.print(".");
    |   }
    |   System.out.println();
    |                                                                      
    |   // close the queue connection
    |   queueConn.close();
    }
                                                                           
    /**
      This method is called asynchronously by JMS when a message arrives
      at the queue. Client applications must not throw any exceptions in
      the onMessage method.
      @param message A JMS message.
     */
    public void onMessage(Message message)
    {
    |   TextMessage msg = (TextMessage) message;
    |   try {
    |   |   System.out.println("received: " + msg.getText());
    |   } catch (JMSException ex) {
    |   |   ex.printStackTrace();
    |   }
    }
                                                                           
    /**
      This method is called asynchronously by JMS when some error occurs.
      When using an asynchronous message listener it is recommended to use
      an exception listener also since JMS has no way to report errors
      otherwise.
      @param exception A JMS exception.
     */
    public void onException(JMSException exception)
    {
    |   System.err.println("an error occurred: " + exception);
    }
}

Multiple Consumers in JMS Queue

When you have multiple consumers, you can distribute the workload for effective and timely processing of messages. In such scenarios, each message in the Queue is delivered to one of the receivers. Because one receiver may process messages quicker than another, the absolute sequence of messages cannot be guaranteed. Once consumed and acknowledged, the message is deleted from the JMS Queue.

To deploy multiple consumer processing on a JMS Queue, you can use the following code:

package com.javacodegeeks.jms;
 
import java.net.URI;
import java.net.URISyntaxException;
 
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
 
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
 
public class JmsMultipleCustomersMessageQueueExample {
    public static void main(String[] args) throws URISyntaxException, Exception {
        BrokerService broker = BrokerFactory.createBroker(new URI(
                "broker:(tcp://localhost:61616)"));
        broker.start();
        Connection connection = null;
        try {
            // Producer
            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                    "tcp://localhost:61616");
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue("customerQueue");
 
            // Consumer
            for (int i = 0; i < 4; i++) {
                MessageConsumer consumer = session.createConsumer(queue);
                consumer.setMessageListener(new ConsumerMessageListener(
                        "Consumer " + i));
            }
            connection.start();
 
            String basePayload = "Important Task";
            MessageProducer producer = session.createProducer(queue);
            for (int i = 0; i < 10; i++) {
                String payload = basePayload + i;
                Message msg = session.createTextMessage(payload);
                System.out.println("Sending text '" + payload + "'");
                producer.send(msg);
            }
 
            Thread.sleep(1000);
            session.close();
        } finally {
            if (connection != null) {
                connection.close();
            }
            broker.stop();
        }
    }
 
}

Code Credits: ​​

Once executed, you will receive an output something like this. The messages you see get ordered in a round-robin fashion.

INFO | PListStore:[C:javacodegeeks_wsjmsMessageTypesExampleactivemq-datalocalhosttmp_storage] started
 INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[C:javacodegeeks_wsjmsMessageTypesExampleactivemq-datalocalhostKahaDB]
 INFO | JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
 INFO | KahaDB is version 6
 INFO | Recovering from the journal @1:173161
 INFO | Recovery replayed 1 operations from the journal in 0.012 seconds.
 INFO | Apache ActiveMQ 5.12.0 (localhost, ID:INMAA1-L1005-62099-1446469937715-0:1) is starting
 INFO | Listening for connections at: tcp://127.0.0.1:61616
 INFO | Connector tcp://127.0.0.1:61616 started
 INFO | Apache ActiveMQ 5.12.0 (localhost, ID:INMAA1-L1005-62099-1446469937715-0:1) started
 INFO | For help or more information please see: http://activemq.apache.org
 WARN | Store limit is 102400 mb (current store usage is 0 mb). The data directory: C:javacodegeeks_wsjmsMessageTypesExampleactivemq-datalocalhostKahaDB only has 34555 mb of usable space - resetting to maximum available disk space: 34556 mb
 WARN | Temporary Store limit is 51200 mb, whilst the temporary data directory: C:javacodegeeks_wsjmsMessageTypesExampleactivemq-datalocalhosttmp_storage only has 34555 mb of usable space - resetting to maximum available 34555 mb.
Sending text 'Important Task0'
Consumer 0 received Important Task0
Sending text 'Important Task1'
Consumer 1 received Important Task1
Sending text 'Important Task2'
Consumer 2 received Important Task2
Sending text 'Important Task3'
Consumer 3 received Important Task3
Sending text 'Important Task4'
Consumer 0 received Important Task4
Sending text 'Important Task5'
Consumer 1 received Important Task5
Sending text 'Important Task6'
Consumer 2 received Important Task6
Sending text 'Important Task7'
Consumer 3 received Important Task7
Sending text 'Important Task8'
Consumer 0 received Important Task8
Sending text 'Important Task9'
Consumer 1 received Important Task9
 INFO | Apache ActiveMQ 5.12.0 (localhost, ID:INMAA1-L1005-62099-1446469937715-0:1) is shutting down
 INFO | Connector tcp://127.0.0.1:61616 stopped
 INFO | PListStore:[C:javacodegeeks_wsjmsMessageTypesExampleactivemq-datalocalhosttmp_storage] stopped
 INFO | Stopping async queue tasks
 INFO | Stopping async topic tasks
 INFO | Stopped KahaDB
 INFO | Apache ActiveMQ 5.12.0 (localhost, ID:INMAA1-L1005-62099-1446469937715-0:1) uptime 2.009 seconds
 INFO | Apache ActiveMQ 5.12.0 (localhost, ID:INMAA1-L1005-62099-1446469937715-0:1) is shutdown

Conclusion

JMS unifies enterprise messaging concepts and facilities into a single messaging service. It’s handy for asynchronous communication across enterprise applications that don’t need to handle requests at the same time. Furthermore, JMS applications are extremely portable across many machine architectures and operating systems, ensuring that you and your team can collaborate and communicate without difficulty.

For ETL starters, crafting an in-house solution can be a daunting task. Third-party ETL tools like Hevo Data reduce time to deployment significantly from months and years to minutes. Our No-Code Automation Platform offers more than 100+ SaaS and BI Data Connectors to readily transfer data from your frequently used applications into a centralized repository like a Data Warehouse.

The best part about Hevo is that setting up Data Pipelines is a cakewalk; select your source, provide credentials and choose your target destination; and you are done.

Visit our Website to Explore Hevo

Hevo can connect your frequently used applications to Data Warehouses like Amazon Redshift, Snowflake, Google BigQuery, Firebolt, or even Database Destinations like PostgreSQL, MySQL, or MS SQL Server in a matter of minutes. Matter of fact, you need no extensive training to use our ETL solution.

Try Hevo and see the magic for yourself. Sign Up here for a 14-day free trial and experience the feature-rich Hevo suite first hand. You can also check our unbeatable pricing and make a decision on your best-suited plan. 

Have any questions on JMS Queue? Do let us know in the comment section below. We’d be happy to help.

No Code Data Pipeline For Your Data Warehouse