Опубликован: 10.10.2010 | Уровень: специалист | Доступ: платный
Лекция 13:

Использование JMS

JMSClient

Класс JMSClient после своего запуска создает соединение с JMS провайдером, создает сессию и MessageProducer,после чего в ответ на каждый ввод пользователя посылает в очередь текстовое сообщение. Работа завершается, если пользователь ввел символ q (или Q ).

1  import javax.jms.ConnectionFactory;
2  import javax.jms.Destination;
3  import javax.jms.Queue;
4  import javax.jms.Topic;
5  import javax.jms.Connection;
6  import javax.jms.Session;
7  import javax.jms.MessageProducer;
8  import javax.jms.TextMessage;
9  import javax.jms.JMSException;
10  import javax.annotation.Resource;
11  import java.io.InputStreamReader;
12  import java.io.IOException;
13  public class JMSClient {
14      @Resource(mappedName = "jms/Example1ConnectionFactory")
15      private static ConnectionFactory connectionFactory;
16      @Resource(mappedName = "jms/Example1Queue")
17      private static Queue queue;

18      public static void main(String[] args) {
19          Connection connection = null;

20          Destination dest = (Destination) queue;

21          try {
22              connection = connectionFactory.createConnection();
23  Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
24              MessageProducer producer = session.createProducer(dest);
25              TextMessage message = session.createTextMessage();
26  InputStreamReader inputStreamReader = new InputStreamReader(System.in);
27              char c = 'n';
28              int i = 0;
29              while (!((c == 'q') || (c == 'Q'))) {
30                  try {
31                      c = (char) inputStreamReader.read();
32                      message.setText("This is message " + (i + 1));
33                      System.out.println("Sending message: " + message.getText());
34                      producer.send(message);    
35                      i++;
36                  } catch (IOException e) {
37                      System.err.println("I/O exception: " + e.toString());
38                  }
39              }
40          } catch (JMSException e) {
41              System.err.println("Exception occurred: " + e.toString());
42          } finally {
43              if (connection != null) {
44                  try {
45                      connection.close();
46                  } catch (JMSException e) {
47                  }
48              }
49          }
50      }
51  }
Листинг 13.1. Класс JMSClient

Программа демонстрирует весь цикл создания типичного JMS приложения. Сначала (строки 14-17) определяются необходимые ресурсы - в данном случае ConnectionFactory и Queue (эти ресурсы с соответствующими именами были ранее созданы).

Затем создаются соединение с JMS -провайдером (строка 22) и сессия (строка 23). Следующим шагом является создание MessageProducer (строка 24) и текстового сообщения (строка 25).

Цикл работы программы (строки 29-39) состоит в ожидании ввода пользователя (строка 31), формировании тела сообщения (строка 32) и его отправки в очередь (строка 34). В конце работы программа закрывает соединение с JMS провайдером (строка 45).

JMSServer

Класс JMSServer служит для обработки сообщений, отправляемых JMSClient. Он синхронным образом считывает сообщения из очереди и печатает их.

1  import javax.jms.ConnectionFactory;
2  import javax.jms.Destination;
3  import javax.jms.Queue;
4  
5  import javax.jms.Connection;
6  import javax.jms.Session;
7  import javax.jms.MessageConsumer;
8  import javax.jms.Message;
9  import javax.jms.TextMessage;
10  import javax.jms.JMSException;
11  import javax.annotation.Resource;
12  public class JMSServer {
13      @Resource(mappedName = "jms/Example1ConnectionFactory")
14      private static ConnectionFactory connectionFactory;
15      @Resource(mappedName = "jms/Example1Queue")
16      private static Queue queue;

17      public static void main(String[] args) {
18          String destType = null;
19          Connection connection = null;
20          Session session = null;
21          Destination dest = (Destination) queue;;
22          MessageConsumer consumer = null;
23          TextMessage message = null;


24          try {
25              connection = connectionFactory.createConnection();
26  session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
27              consumer = session.createConsumer(dest);
28              connection.start();

29              while (true) {
30                  Message m = consumer.receive(1);

31                  if (m != null) {
32                      if (m instanceof TextMessage) {
33                          message = (TextMessage) m;
34                          System.out.println(
35                                  "Reading message: " + message.getText());
36                      } 
37                  }
38              }
39          } catch (JMSException e) {
40              System.err.println("Exception occurred: " + e.toString());
41          } finally {
42              if (connection != null) {
43                  try {
44                      connection.close();
45                  } catch (JMSException e) {
46                  }
47              }
48          }
49      }
50  }
Листинг 13.2. Класс JMSServer

Отличие от предыдущего класса заключается в том, что создается не MessageProducerMessageConsumer (строка 27), поскольку мы собираемся не отправлять сообщения, а принимать их. Для того чтобы начать обработку сообщений, необходимо вызвать метод start (строка 28).

Цикл работы программы (строки 29-38) состоит в ожидании прихода нового сообщения (строка 30). В данном случае ожидание продолжается 1 миллисекунду. Если пришедшее сообщение имеет текстовый тип (именно такие сообщения мы ожидаем получить), оно извлекается и печатается тело сообщения.

Компиляция и запуск

Компиляция приложений JMS не имеет особенностей, единственное, что нужно сделать, - указать соответствующие библиотеки в classpath:

javac   -classpath . ;activation.jar;appserv-ws.jar;javaee.jar;
jsfimpl.jar;appserv-jstl.jar; -d build JMSClient.java
javac   -classpath . ;activation.jar;appserv-ws.jar;javaee.jar;
jsfimpl.jar;appserv-jstl.jar; -d build JMSServer.java

Затем нужно собрать соответствующие пакеты ( jar ):

jar -cvfm server.jar manifest2.mf -C ./build . 
jar -cvfm client.jar manifest.mf -C ./build .

При этом файлы манифеста имеют следующий вид: manifest.mf (пример. 13.3) и manifest2.mf (пример. 13.4).

Manifest-Version: 1.0 
Ant-Version: Apache Ant 1.6.5 
Created-By: asw
Main-Class: JMSClient
Листинг 13.3. Файл manifest.mf
Manifest-Version: 1.0 
Ant-Version: Apache Ant 1.6.5 
Created-By: asw 
Main-Class: JMSServer
Листинг 13.4. Файл manifest2.mf

В результате будут созданы два пакета - server.jar и client.jar.Запуск приложения производится с помощью утилиты appclient, соответственно:

appclient -client client.jar

для клиента (отправителя сообщений) и

appclient -client server.jar

для сервера (обработчика сообщений).

После запуска клиент в ответ на ввод пользователя будет посылать сообщения в очередь, сервер будет их принимать и печатать.

Следует обратить внимание, что сервер и клиент не обязательно должны быть запущены одновременно. Так, клиент, будучи запущенным, может сгенерировать несколько сообщений и закончить работу. Сервер, будучи запущенным позднее, эти сообщения получит, поскольку JMS -провайдер их сохранил.

Ниже приведен пример работы системы.

appclient -client client.jar

Запуск клиента приведет к выводу сообщений об отправке.

Sending message: This is message 1
Sending message: This is message 2
Sending message: This is message 3
Sending message: This is message 4
Sending message: This is message 5
Sending message: This is message 6
Sending message: This is message 7
Sending message: This is message 8
Sending message: This is message 9
Sending message: This is message 10

Запуск сервера:

appclient -client server.jar

приведет к выводу сообщений о приеме.

Reading message: This is message 1
Reading message: This is message 2
Reading message: This is message 3
Reading message: This is message 4
Reading message: This is message 5
Reading message: This is message 6
Reading message: This is message 7
Reading message: This is message 8
Reading message: This is message 9
Reading message: This is message 10
Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


Java version 1.7.0_05
Александр Хвостов
Александр Хвостов
Россия
Максим Лютов
Максим Лютов
Россия, СПб, Политех, 2012