Top-office11.ru

IT и мир ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Javax jms connectionfactory

Javax jms connectionfactory

A ConnectionFactory object encapsulates a set of connection configuration parameters that has been defined by an administrator. A client uses it to create a connection with a JMS provider.

A ConnectionFactory object is a JMS administered object and supports concurrent use.

JMS administered objects are objects containing configuration information that are created by an administrator and later used by JMS clients. They make it practical to administer the JMS API in the enterprise.

Although the interfaces for administered objects do not explicitly depend on the Java Naming and Directory Interface (JNDI) API, the JMS API establishes the convention that JMS clients find administered objects by looking them up in a JNDI namespace.

An administrator can place an administered object anywhere in a namespace. The JMS API does not define a naming policy.

It is expected that JMS providers will provide the tools an administrator needs to create and configure administered objects in a JNDI namespace. JMS provider implementations of administered objects should be both javax.jndi.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts. In addition, it is recommended that these implementations follow the JavaBeans TM design patterns.

This strategy provides several benefits:

  • It hides provider-specific details from JMS clients.
  • It abstracts administrative information into objects in the Java programming language («Java objects») that are easily organized and administered from a common management console.
  • Since there will be JNDI providers for all popular naming services, this means that JMS providers can deliver one implementation of administered objects that will run everywhere.

An administered object should not hold on to any remote resources. Its lookup should not use remote resources other than those used by the JNDI API itself.

Clients should think of administered objects as local Java objects. Looking them up should not have any hidden side effects or use surprising amounts of local resources.

Method Summary
ConnectioncreateConnection ()
Creates a connection with the default user identity.
ConnectioncreateConnection (java.lang.String userName, java.lang.String password)
Creates a connection with the specified user identity.

Method Detail

createConnection

Returns: a newly created connection Throws: JMSException — if the JMS provider fails to create the connection due to some internal error. JMSSecurityException — if client authentication fails due to an invalid user name or password. Since: 1.1

createConnection

Parameters: userName — the caller’s user name password — the caller’s password Returns: a newly created connection Throws: JMSException — if the JMS provider fails to create the connection due to some internal error. JMSSecurityException — if client authentication fails due to an invalid user name or password. Since: 1.1

Overview PackageClass Tree Deprecated Index Help
PREV CLASS NEXT CLASS FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHODDETAIL: FIELD | CONSTR | METHOD
Submit a bug or feature

Copyright © 2009-2011, Oracle Corporation and/or its affiliates. All Rights Reserved. Use is subject to license terms.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Differences between javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory

I’m entering the world of JTA, due to need of distributed transactions, and I’m uncertain about the differences between javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory or more accurately how can it be that javax.jms.ConnectionFactory performed what I expected only javax.jms.XAConnectionFactory can do for me.

The details: I’m using Atomikos essentials as my transaction manager and my app is running on Apache Tomcat 6.

I’m running a small POC with a dummy app where I have my JMS provider ( OpenMQ ) registered as a JNDI resource.

And the strange issue is that in my code I do this:

And later in the code I use this session in a UserTransaction and it performs flawlessly with two MessageProducer s with either Commit or Rollback .

What I don’t understand is how can it be that I’m using javax.jms.XAConnectionFactory.createConnection() method and I get a Session which does the job? What’s javax.jms.XAConnectionFactory role?

I’ll also add that I’ve looked at the source code of both classes (and javax.jms.BasicConnectionFactory ) and I verified that the XA class does not override createConnection .

2 Answers 2

The core of the difference between ConnectionFactory and XAConnectionFactory is that the XAConnectionFactory creates XAConnections which create XASessions. XASessions represent the real difference because (to quote from the JMS JavaDocs:)

The XASession interface extends the capability of Session by adding access to a JMS provider’s support for the Java Transaction API (JTA) (optional). This support takes the form of a javax.transaction.xa.XAResource object.

In other words, the XASession is what gives the XA instances their transactional awareness. However, this specific implementation is optional, even for a fully compliant JMS provider. From the same JavaDoc:

An XAResource provides some fairly sophisticated facilities for interleaving work on multiple transactions, recovering a list of transactions in progress, and so on. A JTA aware JMS provider must fully implement this functionality. This could be done by using the services of a database that supports XA, or a JMS provider may choose to implement this functionality from scratch. A client of the application server is given what it thinks is a regular JMS Session. Behind the scenes, the application server controls the transaction management of the underlying XASession.

In other words, the provider may require that you specify an XA or non-XA JMS resource, or, as would seem to be in your case, the provider may perform all the JTA plumbing transparently with what appears to be a regular JMS Session.

Actually, none of the example code you provided would exercise XA functionality. If all that is required is that your messages are under syncpoint, then you can get by with 1-phase commit (1PC). However if you want, for example, that JMS messages and DB updates occur in a single coordinated unit of work then you would use 2-phase commit (2PC) which is XA. Coordinating across two message producers on the same transport provider does not require XA 2PC.

If you were using 2PC, then in addition to COMMIT and ROLLBACK you would be calling BEGIN somewhere in the code. The lack of that verb in your example is why I said it looks like you are not doing 2PC. The BEGIN call would communicate with the transaction manager to establish a transaction context across the participating resource managers. Then the COMMIT would cause the messages and the DB updates to finalize in one unit of work. The interesting thing here is that if you have only one participating resource manager, some transports will silently optimize you back down to 1PC. In that case it looks as though you are doing 2PC but are really getting 1PC. Since there is only one resource manager there is no loss of reliability in this optimization.

On the other hand, if you are doing 1PC you won’t see any difference between the two types of connection factory. It would exhibit exactly the behavior you describe.

The last case to consider is that you use ConnectionFactory and try to call BEGIN. Since the non-XA connection factory cannot participate in a coordinated XA transaction, this call should fail.

Работа с JMS сообщениями и MDB в JEE

Работа с сообщениями подразумевает взаимодействие между компонентами системы посредством передачи сообщений. JMS позволяет реализовать это взаимодействие в java приложении, а MDB бины позволяют асинхронно обрабатывать получаемые сообщения на сервере приложений без дополнительных усилий по асинхронной обработке.

Ниже представлен простой пример обработки JMS сообщения с помощью MDB.

Немного теории

Для работы с сообщениями используется вспомогательное программное обеспечение, обычно входящее в поставку сервера приложений.
Компоненты системы могут посылать сообщения (producer) и получать их (consumer). Сообщение
отправляет producer на пункт назначения (destination), являющимся на сервере queue или topic, после чего consumer может забрать оттуда сообщение
В зависимости от того, какой тип имеет destination, разделяют две модели работы с сообщениями.

Первая модель — Point-to-Point

В случае если на сервере destination имеет тип queue, то сообщение, которое отправил producer, получает единственный consumer. Если на эту очередь сообщений подписано несколько получателей, то сообщение получит только один из них.

Вторая модель — Publish-subscribe

В случае если на сервере destination имеет тип topic, то одно сообщение может быть прочитано неограниченным количеством consumer, подписанных на этот на этот destination.

Структура JMS сообщения

Сообщение состоит из заголовка, поля свойств и тела.
Заголовок хранит мета информацию сообщения, заполняемую автоматически.
Поле свойств схоже с заголовком, но оно заполняется программно, и позже получатель сможет прочитать эту информацию.
Тело содержит полезную нагрузку сообщения. Тип нагрузки определяется при создании сообщения. Конкретные типы унаследованы от интерфейса javax.jms.Message

Создание очереди на сервере.

Для примера создадим topic на сервере. Использовать я буду glassfish 3.1.
Для начала создадим Connection Factory. Возможны несколько типов в зависимости от того, какой тип очереди сообщений будет использоваться.

Затем создаем destination с указание типа.

Создание отправителя сообщений

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

Message-Driven Bean

Для обработки приходящих сообщений на сервере мы будем использовать MDB.

Сообщения можно было бы получать и обрабатывать и с помошью pojo, выступающего как consumer. Но использование MDB позволит параллельно обрабатывать сообщения, не заботясь о сложности асинхронной обработки и дополнительного кода для подписки на очередь сообщений.
Асинхронная обработка реализуется через пул объектов, из которых на обработку сообщения сервер выделят объекты при необходимости.

Для реализации MBD достаточно унаследовать бин от интерфейса javax.jms.MessageListener, реализуя метод onMessage(), и аннотировать соответствующим образом класс.

Сделаем пример MDB, который выводит в консоль сервера информацию о поступившем сообщении.

В onMessage метод добавляется необходимая бизнес логика, в зависимости от типа сообщения, его содержания и тд.
При необходимости, для ручной обработки сообщений можно самостоятельно создать обработчика.
Например так:

Для более подробного изучения JMS и EJB в целом, могу рекомендовать книги:
EJB 3 in Action — Debu Panda, Reza Rahman, Derek Lane
Пару книг от Adam Bien

Читать еще:  Java android intent
Ссылка на основную публикацию
Adblock
detector