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

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

Первое знакомство

Использование JMS предполагает выполнение разработчиком последовательности шагов. Ниже приведена общая схема применения JMS API.

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

Общая схема использования JMS API

Рис. 13.4. Общая схема использования JMS API

Для этого используется специальная фабрика объектов - ConnectionFactory. ConnectionFactory на самом деле является интерфейсом, от которого наследуют QueueConnectionFactory, TopicConnectionFactory, XAQueueConnectionFactory и XATopicConnectionFactory.Таким образом, мы будем иметь дело с реализацией одного из этих интерфейсов. Для того чтобы получить доступ к ConnectionFactory,программа должна извлечь соответствующую ссылку из JNDI. С использованием механизма аннотаций соответствующий код будет иметь следующий вид:

@>Resource(mappedName="jms/ConnectionFactory") 
private static ConnectionFactory connectionFactory;

Указанный фрагмент кода извлекает ресурс с JNDI -именем jms/ConnectionFactory и связывает его с переменной connectionFactory.

Естественно, перед первым применением ConnectionFactory должна быть создана командой

asadmin.bat create-jms-resource --user admin --passwordfile 
admin-password.txt --host localhost   --port 4848 --restype 
javax.jms.ConnectionFactory --enabled=true   jms/ConnectionFactory

Данная команда создает ресурс типа javax.jms.ConnectionFactory с именем jms/ConnectionFactory .

Следующим шагом является создание соединения с JMS провайдером. Соответствующий код будет выглядеть следующим образом:

Connection connection = connectionFactory.createConnection();

Следует отметить, что соединение должно быть закрыто после того, как оно перестает использоваться (connection.close()).

После того как соединение создано, могут быть созданы виртуальные каналы, в рамках которых будет осуществляться передача сообщений. Существуют два типа таких каналов - очередь ( Queue ) и тема ( Topic ). Следует отметить, что создание виртуального канала требует наличия соответствующего "пункта назначения" ( destination ), созданного в JNDI. Таким образом, прежде чем программа сможет задействовать очередь (или тему), соответствующий объект должен быть создан в JMS -провайдере. Для Sun Application Server соответствующая команда будет иметь вид:

asadmin.bat create-jms-resource --user admin --passwordfile 
admin-password.txt --host localhost --port 4848 --restype
javax.jms.Queue --enabled=true --property Name=PhysicalQueue jms/Queue

где restype указывает тип объекта - в данном случае это javax.jms.Queue,а параметр property задает JNDI имя объекта - jms/Queue.

Для того, чтобы в программе получить ссылку на соответствующий объект, можно использовать код вида

@>Resource(mappedName="jms/Queue") private static Queue queue;

для очереди, или, если нужно получить ссылку на объект типа тема:

@>Resource(mappedName="jms/Topic") private static Topic topic;

Еще раз обращаем внимание на то, что объекты с именами jms/Queue или jms/Topic должны быть предварительно созданы.

После того как соединение с JMS провайдером установлено и получены ссылки на соответствующие пункты назначения (очередь или тема), может начаться собственно процесс обмена сообщениями.

Весь процесс обмена происходит в рамках сессии ( Session ), которая представляет собой однопотоковый контекст для обмена сообщениями. Сессия также предоставляет транзакционный контекст для обеспечения атомарности выполнения групп передач/приемов сообщений1Сессии с поддержкой транзакционности в данном разделе не рассматриваются . Сессия может быть создана следующим образом:

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

где первый параметр указывает на то, что секция не транзакционна, а второй параметр указывает на то, что необходимо автоматически подтверждать успешную доставку сообщений.

В рамках сессии приложение может создать ряд объектов, обеспечивающих отправку и приемку сообщений. Это Message Producers и Message Consumers.

Создаются эти объекты следующим образом:

MessageProducer producer = session.createProducer(queue); 
MessageConsumer consumer = session.createConsumer(queue);

В качестве аргумента методы создания требуют указания пункта назначения. После создания посредством MessageProducer приложение может отправлять сообщения, а посредством MessageConsumer - принимать. Для отправки сообщения достаточно вызвать метод send, передав ему в качестве аргумента объект типа Message:

producer.send(message)

Для синхронного приема сообщения необходимо сначала запустить диспетчеризацию сообщения, затем вызвать метод receive соответствующего MessageConsumer.Метод receive является блокирующим, однако он может быть вызван с указанием количества миллисекунд, в течение которых он должен ожидать чтения сообщения.

connection.start();
Message m = consumer.receive();

при этом управление вернется в момент прихода сообщения, или

connection.start();
Message m = consumer.receive(2000);

При этом управление вернется в момент прихода сообщения или по истечении 2 секунд.

Для асинхронного приема сообщения может быть создан специальный класс - листенер, который должен быть зарегистрирован в рамках данного MessageConsumer и метод которого onMessage будет вызван в момент прихода сообщения.

Listener myListener = new Listener(); 
consumer.setMessageListener(myListener);

Типы сообщений

Сообщение в JMS - это объект Java, состоящий из двух частей: заголовка ( header ) и тела ( body ) сообщения. В заголовке находится служебная информация, тело сообщения содержит в себе пользовательские данные, которые могут быть разной формы: текстовой, сериализуемых объектов, байтовых потоков и т. д.

JMS API определяет несколько типов сообщений:

  • BytesMessage предназначен для передачи потока байт, который система никак не интерпретирует;
  • MapMessage предназначен для передачи множества элементов типа "имя-значение", где имена являются объектами строкового типа, а значения - объектами примитивных типов данных Java ;
  • ObjectMessage предназначен для передачи сериализуемых объектов;
  • StreamMessage предназначен для передачи множества элементов примитивных типов данных Java (они могут быть последовательно записаны, а затем прочитаны из тела сообщения этого типа);
  • TextMessage предназначен для передачи текстовой информации.

Первая программа

Приведем практический пример применения рассмотренных технологий и пройдем по шагам все этапы создания приложения с использованием JMS.

Во-первых, нам потребуется JMS -провайдер. В качестве такового будет использован встроенный сервис Sun Java System Application Server, поставляемый в составе пакета J2EE. Инсталляция этого сервера приложений была рассмотрена ранее.

Административная консоль. Создание ConnectionFactory

Рис. 13.5. Административная консоль. Создание ConnectionFactory

Как уже говорилось ранее, первым шагом при разработке JMS приложения является создание необходимых ресурсов. Первый ресурс, который будет нами создан, - ConnectionFactory.В нашем случае это делается командой

asadmin.bat create-jms-resource -user admin --passwordfile 
admin-password.txt --host localhost   --port 4848 --restype 
javax.jms.ConnectionFactory --enabled=true 
jms/Exаmple1ConnectionFactory

Убедиться, что указанный ресурс создан, можно с помощью административной консоли2Все действия, выполняемые нами с помощью утилиты asadmin, могут быть выполнены посредством административной консоли .

Следующим ресурсом, который необходимо создать, является "пункт назначения". Для нашего примера будет создан пункт назначения типа "очередь" с именем Example1Queue:

Административная консоль. Создание пункта назначения

Рис. 13.6. Административная консоль. Создание пункта назначения
asadmin.bat create-jms-resource --user admin --passwordfile 
admin-password.txt --host localhost --port 4848 --restype 
javax.jms.Queue --enabled=true --property Name=PhysicalQueue 
jms/Exаmple1Queue

Как и в случае с ConnectionFactory,созданный объект доступен в административной консоли.

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

Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


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