JMS (Java messaging Service) is a standard defined in Java EE to address the producer consumer problem. It standardizes the way of message exchange between two or more system. JMS can be vaguely related to Webservice as they both do the same tasks sending and receiving message. But the main difference lies is Webservice are Synchronous and JMS is asynchronous. Also, we can relate JMS and messaging queues provided different vendor such as WebSphere MQ, ActiveMQ, RabbitMQ etc. AMQP and Microsoft messaging queue does not implement JMS. You can bind JMS inside a EJB same as other locale remote network access using java interfaces, webservices etc. Loos coupling, reliability and asynchronous are main characteristics. Here are JMS component.

You will need a JMS provider server.

You can use Active MQ, Rabbit MQ, Websphere MQ etc, which ever you like and configure few queues in that and get the URL, username password, queue name etc.

Different options to configure JMS

Using Application Server : Since JMS is a specification this is supported by many enterprise level application server for ex IBM Websphere, Weblogic etc. You can configure the JMS URL, queue name, id password etc at Application server level and get it working.

Using Spring Framework : Overall spring tries to reduce the Job for Application server, Spring provides very light option to support Java specification implementation and one of them is JMS. You can choose to use spring framework to configure JMS client and use JMSTemplate to receive or send the message.

Spring Approach.

Add following dependency to your pom.xml.

For Active MQ

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.activemq</groupId>
  <artifactId>activemq-broker</artifactId>
</dependency>
<!-- Or just starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

For Websphere MQ

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
</dependency>
<dependency>
    <groupId>com.ibm.mq</groupId>
    <artifactId>mq-jms-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

Sending Message to Active MQ.

Sending requires, spring jmsTemplate, Spring CachingConnectionFactory and Provider provided connection factory.

package com.xyz.jms;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;

@Configuration
public class JMSSenderConfiguratipn {

  @Value("${activemq.brokerUrl}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory createActiveMQConnectionFactory() {
    ActiveMQConnectionFactory factory =
        new ActiveMQConnectionFactory();
    factory.setBrokerURL(brokerUrl);

    return factory;
  }

  @Bean
  public CachingConnectionFactory creachCachingConnectionFactory() {
    return new CachingConnectionFactory(
        createActiveMQConnectionFactory());
  }

  @Bean
  public JmsTemplate jmsTemplate() {
    return new JmsTemplate(creachCachingConnectionFactory());
  }
}

// Send message.
@Autowired
private JmsTemplate jmsTemplate;

public void send(String msg) {
  jmsTemplate.convertAndSend("senderQueuename", msg);
}

Recieving Message from Active MQ.

Receiving requires @EnableJms, Spring DefaultJmsListenerContainerFactory and Provider provided connection. package com.xyz.jms;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;

@Configuration
@EnableJms
public class JMSRecieverConfiguratipn {

  @Value("${activemq.brokerUrl}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory createActiveMQConnectionFactory() {
    ActiveMQConnectionFactory factory =
        new ActiveMQConnectionFactory();
    factory.setBrokerURL(brokerUrl);

    return factory;
  }

  @Bean
  public DefaultJmsListenerContainerFactory  creachCachingConnectionFactory() {
    return new DefaultJmsListenerContainerFactory (
        createActiveMQConnectionFactory());
  }
}

//receive message
@JmsListener(destination = "recieverQueuename")
public void receive(String msg) {
  // use msg.  // It is asynchronusly invoked
}
// Or 
@Autowired
private JmsTemplate jmsTemplate;
.....
jmsTemplate.receiveAndConvert("DEV.QUEUE.1").toString(); // It blocks the flow. 

Send & Recive message to Websphere MQ.

Since we are using Spring JMS Websphere MQ started jar, the jmsTemplate is already created which you can use anywhere in your code. Add @EnableJMS to your configuration class and add the following key value pair in property file.

ibm.mq.queueManager=QM1
ibm.mq.channel=DEV.ADMIN.SVRCONN
ibm.mq.connName=localhost(1414)
ibm.mq.user=username
ibm.mq.password=password