Enterprise Java Messaging Service JMS v 121128 JMS

  • Slides: 90
Download presentation
Enterprise Java Messaging Service (JMS) v 121128 JMS 1

Enterprise Java Messaging Service (JMS) v 121128 JMS 1

Goals Enterprise Java • Understand the basic concepts behind messaging and the Java Messaging

Goals Enterprise Java • Understand the basic concepts behind messaging and the Java Messaging Service (JMS) API • Be able to define a destination using a JMS provider • Be able to create a Java SE JMS producer and consumer – publisher/subscriber – sender/receiver v 121128 JMS 2

Objectives • • Enterprise Java Messaging Overview JMS Examples JMS API Detail v 121128

Objectives • • Enterprise Java Messaging Overview JMS Examples JMS API Detail v 121128 JMS 3

Messaging Enterprise Java • Communication between applications that exchange messages – Message forms a

Messaging Enterprise Java • Communication between applications that exchange messages – Message forms a single, encapsulated, unit of communication between applications • De-couples Producer and Consumer of the Message • Message-Oriented-Middleware (MOM) – category of application communication – uses asynchronous message passing versus synchronous request/reply • Advantages – Producer and Consumer operate independently • Messages can be persisted when consumer unavailable • Messages can be retrieved even after producer is unavailable – Qualities of service can be applied independent of clients – Resource utilization can be applied by messaging provider v 121128 JMS 4

MOM Architecture: Direct Connections Enterprise Java • • • Producer/Consumer communicate over a TCP/IP

MOM Architecture: Direct Connections Enterprise Java • • • Producer/Consumer communicate over a TCP/IP connection Directly aware of state of link Producer cannot send messages when Consumer unavailable Consumer cannot receive messages when Producer unavailable Separate messages must be sent to separate clients – Producer must be aware of what Consumer needs • Security and Qo. S must be implemented by entirely within clients • Good for realtime status networks v 121128 JMS 5

Enterprise Java MOM Architecture: Unicast Connections • Producer/Consumer communicate over a Uni-cast IP •

Enterprise Java MOM Architecture: Unicast Connections • Producer/Consumer communicate over a Uni-cast IP • No concept of an end-to-end link • Producer issues messages whether Consumer available or not – MOM can add acknowledgment and queuing mechanisms • Consumer cannot receive messages when Producer unavailable • Producer only needs to send one message – Consumers able to control when they receive • Security and Qo. S must be implemented by entirely within clients • Good for high performance publish/subscribe networks v 121128 JMS 6

MOM Architecture: Broker-based Enterprise Java • Producer/Consumer communicate to a separate broker • No

MOM Architecture: Broker-based Enterprise Java • Producer/Consumer communicate to a separate broker • No concept of an end-to-end link • Producer issues messages whether Consumer available or not – application can add acknowledgment mechanisms • Consumer can receive messages when Producer unavailable • Producer only needs to send one message – Consumers able to control when they receive • Security and Qo. S can be implemented within broker (thin client) • Good for fully decoupling messaging complexity from clients v 121128 JMS 7

MOM Architecture: Multi-Broker Enterprise Java • Clients unaware of physical topology • MOM Brokers

MOM Architecture: Multi-Broker Enterprise Java • Clients unaware of physical topology • MOM Brokers link can – honor time-of-day bandwidth constraints – conserve bandwidth between sites by only sending what is needed – point of site-to-site firewall control – form alternate routing v 121128 JMS 8

Messaging Domains: Key Concepts Enterprise Java • Producer – produces message • Destination –

Messaging Domains: Key Concepts Enterprise Java • Producer – produces message • Destination – target of produced message – source of consumed message – hosted by messaging provider • Consumer – consumes message v 121128 JMS 9

Messaging Domains: Queuing Enterprise Java • Sender – a Producer – sends message to

Messaging Domains: Queuing Enterprise Java • Sender – a Producer – sends message to a Queue with a specific target/intent • Queue – a Destination – delivers message to, at most, one receiver • Receiver – a Consumer – intended target of message v 121128 JMS 10

Messaging Domains: Publish/Subscribe Enterprise Java • Publisher – a Producer – publishes message to

Messaging Domains: Publish/Subscribe Enterprise Java • Publisher – a Producer – publishes message to Topic with no specific target/intent • Topic – a Destination – delivers message to active Subscribers • Subscriber – a Consumer – has registered interest in a Topic • durable subscription – lives beyond active client connection • non-durable subscription – only exists during client connection v 121128 JMS 11

Messaging Domains: Request/Reply Enterprise Java • Requestor – sends message to a destination appropriate

Messaging Domains: Request/Reply Enterprise Java • Requestor – sends message to a destination appropriate to be available to a Replier – receives reply for request • Request Destination – can be Topic or Queue • Reply Destination – can be Topic or Queue (typically a Queue) • Replier – receives request message from destination – sends reply message to destination specified in request v 121128 JMS 12

Messaging and Transactions Enterprise Java • Each interaction with Destination can be made part

Messaging and Transactions Enterprise Java • Each interaction with Destination can be made part of an existing ACID transaction – Transaction #1 • Requestor – begins some work – sends message to a destination appropriate to be available to a Replier – Transaction #2 • Replier – receives request message from destination – performs work – sends reply message to destination specified in request – Transaction #3 • Requestor – receives reply for request – completes work v 121128 JMS 13

JMS Background Enterprise Java • Vendor-neutral API to access enterprise messaging systems. – Similar

JMS Background Enterprise Java • Vendor-neutral API to access enterprise messaging systems. – Similar API role as JDBC • JDBC is an API for accessing RDBMS • JMS is an API for accessing enterprise messaging systems • API between the application (JMS client) and the messaging provider (JMS provider); not between providers – Similar non-role as JDBC • JDBC won't cause data inserted into an HSQL instance to magically show up in an Oracle instance • JMS won't cause a message sent to a JBoss. MQ destination to magically show up in a BEA instance's destination • Its a Java API; no other languages addressed – JMS providers accommodate other language clients using proprietary non-Java APIs v 121128 JMS 14

Not Specified By JMS Enterprise Java • Security – How are destinations secured •

Not Specified By JMS Enterprise Java • Security – How are destinations secured • Load Balancing/Fault Tolerance – How do Topics scale to many publishers/subscribers – How does a provider account for broker failure • Error Notifications – What happens when storage exhausted – FIFO? , LIFO? retention • Administration – How are destinations and connection factories added • Message Repository – How is storage allocated • Wire Protocol – RMI? SOAP/HTTP? Other? • Interoperability with non-Java clients v 121128 JMS 15

JMS Examples Enterprise Java • Notifier – Publish/Subscribe • non-durable and durable subscriptions –

JMS Examples Enterprise Java • Notifier – Publish/Subscribe • non-durable and durable subscriptions – One-way Message traffic • Scheduler – Request/Reply • request queue • temporary response queue • dead letter queue – Transactional receive/send – Load distribution v 121128 JMS 16

JMS Notifier Example Enterprise Java src/ |-- main | `-- java | `-- examples

JMS Notifier Example Enterprise Java src/ |-- main | `-- java | `-- examples | `-- jmsnotifier | |-- Publisher. java | `-- Subscriber. java `-- test |-- java | `-- examples | `-- jmsnotifier | `-- JMSNotifier. IT. java `-- resources |-- jms. Notifier-ant. xml |-- jms. Notifier. properties |-- jndi. properties `-- log 4 j. xml v 121128 JMS 17

JMS Notifier: Topic Configuration Enterprise Java • JBOSS_HOME/standalone/configuration/standalone. xml <subsystem xmlns="urn: jboss: domain: messaging:

JMS Notifier: Topic Configuration Enterprise Java • JBOSS_HOME/standalone/configuration/standalone. xml <subsystem xmlns="urn: jboss: domain: messaging: 1. 1"> <hornetq-server>. . . <security-settings> <security-setting match="#"> <permission type="send" roles=" publisher user"/> <permission type="consume" roles=" subscriber user"/> <permission type="create. Durable. Queue" roles=" subscriber user"/> <permission type="delete. Durable. Queue" roles="user"/> <permission type="create. Non. Durable. Queue" roles=" subscriber user"/> <permission type="delete. Non. Durable. Queue" roles="user"/> </security-settings> <jms-destinations> <jms-topic name=" jms. Notifier-test. Topic 1"> <entry name="java: jboss/exported/topic/ejava/examples/jms. Notifier/topic 1 “/> </jms-topic> v 121128 JMS 18

JMS Notifier: jms. Notifier-ant. xml Enterprise Java • publisher target(s) run Publisher <target name="publisher">

JMS Notifier: jms. Notifier-ant. xml Enterprise Java • publisher target(s) run Publisher <target name="publisher"> <java classname="ejava. examples. jmsnotifier. Publisher"> <classpath> <path refid="demo. classpath"/> </classpath> <arg value="-jndi. name. conn. Factory"/> <arg value="${jndi. name. conn. Factory}"/> <arg value="-jndi. name. destination"/> <arg value="${jndi. name. test. Topic}"/> <arg value="-name"/> <arg value="${publisher. name}"/> <arg value="-sleep"/> <arg value="${publisher. sleep}"/> <arg value="-max"/> <arg value="${publisher. max}"/> </java> </target> v 121128 JMS 19

JMS Notifier: jms. Notifier-ant. xml Enterprise Java • subscriber target(s) run Subscriber <target name="subscriber">

JMS Notifier: jms. Notifier-ant. xml Enterprise Java • subscriber target(s) run Subscriber <target name="subscriber"> <java classname="ejava. examples. jmsnotifier. Subscriber"> <classpath> <path refid="demo. classpath"/> </classpath> <arg value="-jndi. name. conn. Factory"/> <arg value="${jndi. name. conn. Factory}"/> <arg value="-jndi. name. destination"/> <arg value="${jndi. name. test. Topic}"/> <arg value="-name"/> <arg value="${subscriber. name}"/> <arg value="-sleep"/> <arg value="${subscriber. sleep}"/> <arg value="-max"/> <arg value="${subscriber. max}"/> <arg value="-durable"/> <arg value="${subscriber. durable}"/> <arg value="-selector"/> <arg value="${subscriber. selector}"/> v 121128 </java> JMS </target> 20

JMS Notifier: jms. Notifier. properties Enterprise Java • m 2. repo and jboss. home

JMS Notifier: jms. Notifier. properties Enterprise Java • m 2. repo and jboss. home must be set by local environment M 2_REPO=${m 2. repo} JBOSS_HOME=${jboss. home} javaee. classpath=${M 2_REPO}/javax/javaee/5/javaee-5. jar commons. logging. classpath=${M 2_REPO}/commons-logging/commonslogging/1. 0. 4/commons-logging 1. 0. 4. jar: ${M 2_REPO}/xerces. Impl/2. 6. 2/xerces. Impl-2. 6. 2. jar log 4 j. classpath=${M 2_REPO}/log 4 j/1. 2. 13/log 4 j-1. 2. 13. jar jbossall-client. classpath=${JBOSS_HOME}/client/jbossall-client. jar jndi. name. conn. Factory=Connection. Factory jndi. name. test. Topic=topic/ejava/examples/jms. Notifier/topic 1 publisher. name=Publisher 0 publisher. sleep=1000 publisher. max=0 subscriber. name=Subscriber 0 subscriber. sleep=0 subscriber. max=0 subscriber. durable=false subscriber. selector= v 121128 JMS 21

Running Publisher Enterprise Java jms. Notifier> mvn process-test-resources; ant -f target/testclasses/jms. Notifier-ant. xml init

Running Publisher Enterprise Java jms. Notifier> mvn process-test-resources; ant -f target/testclasses/jms. Notifier-ant. xml init publisher. . . init: [copy] Copying 1 file to /apps/jboss/server/default/deploy publisher: [java] Publisher args: -jndi. name. conn. Factory Connection. Factory jndi. name. destination topic/ejava/examples/jms. Notifier/topic 1 -name Publisher 0 -sleep 1000 -max 0 [java] -publisher Publisher 0 starting: max. Count=0, sleep. Time 1000 [java] -published message(1): ID: 19 -11645872898981 [java] -published message(2): ID: 19 -11645872909152 [java] -published message(3): ID: 19 -11645872919193. . . v 121128 JMS 22

Running Subscriber 0 Enterprise Java • Subscriber 0 receives all messages jms. Notifier> mvn

Running Subscriber 0 Enterprise Java • Subscriber 0 receives all messages jms. Notifier> mvn process-test-resources; ant -f target/testclasses/jms. Notifier-ant. xml subscriber -emacs. . . subscriber: -subscriber Subscriber 0 starting: durable=false, selector= -Subscriber 0 received message #5, msg. Id=ID: 20 -1164587642313196, body=count = 196 -Subscriber 0 received message #6, msg. Id=ID: 20 -1164587643325197, body=count = 197 -Subscriber 0 received message #7, msg. Id=ID: 20 -1164587644330198, body=count = 198 -Subscriber 0 received message #8, msg. Id=ID: 20 -1164587645337199, body=count = 199 -Subscriber 0 received message #9, msg. Id=ID: 20 -1164587646342200, body=count = 200 -Subscriber 0 received message #10, msg. Id=ID: 20 -1164587647350201, body=count = 201 -Subscriber 0 received message #11, msg. Id=ID: 20 -1164587648354202, body=count = 202 -Subscriber 0 received message #12, msg. Id=ID: 20 -1164587649358203, body=count = 203 -Subscriber 0 received message #13, msg. Id=ID: 20 -1164587650366204, body=count = 204 v 121128 JMS 23

Running Subscriber 0 Enterprise Java • Subscriber 1 receives all messages matching selector jms.

Running Subscriber 0 Enterprise Java • Subscriber 1 receives all messages matching selector jms. Notifier> ant -f target/test-classes/jms. Notifier-ant. xml subscriber 1 -emacs. . . subscriber 1: -subscriber Subscriber 1 starting: durable=false, selector=count((count/4)*4)=0 -Subscriber 1 received message #1, msg. Id=ID: 20 -1164587642313196, body=count = 196 -Subscriber 1 received message #2, msg. Id=ID: 20 -1164587646342200, body=count = 200 -Subscriber 1 received message #3, msg. Id=ID: 20 -1164587650366204, body=count = 204 v 121128 JMS 24

JMS Scheduler Enterprise Java src/ |-- main | `-- java | `-- examples |

JMS Scheduler Enterprise Java src/ |-- main | `-- java | `-- examples | `-- jmsscheduler | |-- Requestor. java | `-- Worker. java `-- test |-- java | `-- examples | `-- jmsscheduler | `-- JMSScheduler. IT. java `-- resources |-- jms. Scheduler-ant. xml |-- jms. Scheduler. properties |-- jndi. properties `-- log 4 j. xml v 121128 JMS 25

JMS Scheduler: Queue Configuration Enterprise Java • JBOSS_HOME/standalone/configuration/standalone. xml <subsystem xmlns="urn: jboss: domain: messaging:

JMS Scheduler: Queue Configuration Enterprise Java • JBOSS_HOME/standalone/configuration/standalone. xml <subsystem xmlns="urn: jboss: domain: messaging: 1. 1"> <hornetq-server>. . . </security-settings> <security-setting match="jms. queue. jms. Scheduler-request. Queue"> <permission type="send" roles=" requestor"/> <permission type="consume" roles=" worker"/> <permission type="create. Non. Durable. Queue" roles=" requestor"/> </security-setting> <security-setting match="jms. queue. jms. Scheduler-DLQ"> <permission type="send" roles=" worker"/> <permission type="consume" roles="admin"/> </security-settings> <jms-destinations> <jms-queue name=" jms. Scheduler-request. Queue "> <entry name="java: jboss/exported/queue/ejava/examples/jms. Scheduler/request. Queue "/> </jms-queue> <jms-queue name=" jms. Scheduler-DLQ"> <entry name=" java: jboss/exported/queue/jms. Scheduler/DLQ "/> </jms-queue> v 121128 JMS 26

JMS Scheduler: jms. Scheduler-ant. xml Enterprise Java • requestor target(s) run Requestor <target name="requestor">

JMS Scheduler: jms. Scheduler-ant. xml Enterprise Java • requestor target(s) run Requestor <target name="requestor"> <java classname="ejava. examples. jmsscheduler. Requestor"> <classpath> <path refid="demo. classpath"/> </classpath> <arg value="-jndi. name. conn. Factory"/> <arg value="${jndi. name. conn. Factory}"/> <arg value="-jndi. name. destination"/> <arg value="${jndi. name. test. Queue}"/> <arg value="-jndi. name. DLQ"/> <arg value="${jndi. name. DLQ}"/> <arg value="-name"/> <arg value="${requestor. name}"/> <arg value="-sleep"/> <arg value="${requestor. sleep}"/> <arg value="-max"/> <arg value="${requestor. max}"/> </java> </target> v 121128 JMS 27

JMS Scheduler: jms. Scheduler-ant. xml Enterprise Java • worker target(s) run Worker <target name="worker">

JMS Scheduler: jms. Scheduler-ant. xml Enterprise Java • worker target(s) run Worker <target name="worker"> <java classname="ejava. examples. jmsscheduler. Worker"> <classpath> <path refid="demo. classpath"/> </classpath> <arg value="-jndi. name. conn. Factory"/> <arg value="${jndi. name. conn. Factory}"/> <arg value="-jndi. name. destination"/> <arg value="${jndi. name. test. Queue}"/> <arg value="-jndi. name. DLQ"/> <arg value="${jndi. name. DLQ}"/> <arg value="-name"/> <arg value="${worker. name}"/> <arg value="-max"/> <arg value="${worker. max}"/> </java> </target> v 121128 JMS 28

JMS Scheduler: jms. Scheduler. properties Enterprise Java • m 2. repo and jboss. home

JMS Scheduler: jms. Scheduler. properties Enterprise Java • m 2. repo and jboss. home must be set by local environment M 2_REPO=${m 2. repo} JBOSS_HOME=${jboss. home} javaee. classpath=${M 2_REPO}/javax/javaee/5/javaee-5. jar commons. logging. classpath=${M 2_REPO}/commons-logging/commonslogging/1. 0. 4/commons-logging 1. 0. 4. jar: ${M 2_REPO}/xerces. Impl/2. 6. 2/xerces. Impl-2. 6. 2. jar jbossall-client. classpath=${JBOSS_HOME}/client/jbossall-client. jar log 4 j. classpath=${M 2_REPO}/log 4 j/1. 2. 13/log 4 j-1. 2. 13. jar jndi. name. conn. Factory=Connection. Factory jndi. name. test. Queue=queue/ejava/examples/jms. Scheduler/request. Queue jndi. name. DLQ=queue/ejava/examples/jms. Scheduler/DLQ requestor. name=Requestor 0 requestor. sleep=5000 requestor. max=10 requestor 1. name=Requestor 1 requestor 1. sleep=10 requestor 1. max=0 worker. name=Worker 0 worker. max=0 v 121128 JMS 29

jms. Scheduler: Requestor 0 Enterprise Java • Requestor sends request to queue and tracks

jms. Scheduler: Requestor 0 Enterprise Java • Requestor sends request to queue and tracks reply jms. Scheduler> mvn process-test-resources; ant -f target/test-classes/jms. Schedulerant. xml init requestor -emacs. . . Requestor args: -jndi. name. conn. Factory Connection. Factory -jndi. name. destination queue/ejava/examples/jms. Scheduler/request. Queue -jndi. name. DLQ queue/ejava/examples/jms. Scheduler/DLQ -name Requestor 0 -sleep 5000 -max 10 -requester Requestor 0 starting: max. Count=10, sleep. Time 5000 -published message(1): ID: 30 -11645891529921 -outstanding requests=1 -recieved response for: 1, from Worker 0, outstanding=0 -published message(2): ID: 30 -11645891580212 -outstanding requests=1 -recieved response for: 2, from Worker 1, outstanding=0 -published message(3): ID: 30 -11645891630903 -outstanding requests=1. . . -recieved response for: 6, from Worker 0, outstanding=0 -published message(7): ID: 30 -11645891831377 -outstanding requests=1. . . -recieved response for: 10, from Worker 0, outstanding=0 -requester Requestor 0 stopping, count=10 v 121128 JMS 30

jms. Scheduler: Worker 0 Enterprise Java • Worker 0 takes next request, processes, and

jms. Scheduler: Worker 0 Enterprise Java • Worker 0 takes next request, processes, and replies jms. Scheduler> ant -f target/test-classes/jms. Scheduler-ant. xml worker -emacs worker: Worker args: -jndi. name. conn. Factory Connection. Factory -jndi. name. destination queue/ejava/examples/jms. Scheduler/request. Queue -jndi. name. DLQ queue/ejava/examples/jms. Scheduler/DLQ -name Worker 0 -max 0 -worker Worker 0 starting -Worker 0 received message #1, req=1, reply. To=QUEUE. JMS_TQ 3, delay=0 -committing session -Worker 0 received message #2, req=3, reply. To=QUEUE. JMS_TQ 3, delay=0 -committing session -Worker 0 received message #3, req=5, reply. To=QUEUE. JMS_TQ 3, delay=10 -committing session -Worker 0 received message #4, req=6, reply. To=QUEUE. JMS_TQ 3, delay=10 -committing session -Worker 0 received message #5, req=7, reply. To=QUEUE. JMS_TQ 3, delay=10 -committing session -Worker 0 received message #6, req=8, reply. To=QUEUE. JMS_TQ 3, delay=100 -committing session -Worker 0 received message #7, req=9, reply. To=QUEUE. JMS_TQ 3, delay=100 -committing session -Worker 0 received message #8, req=10, reply. To=QUEUE. JMS_TQ 3, delay=0 -committing session v 121128 JMS 31

jms. Scheduler: Worker 1 Enterprise Java • Worker 1 competes for requests • Quits

jms. Scheduler: Worker 1 Enterprise Java • Worker 1 competes for requests • Quits after 3 requests – 2 completed successfully – 3 rd never committed jms. Scheduler> ant -f target/test-classes/jms. Scheduler-ant. xml worker 1 -emacs Buildfile: target/test-classes/jms. Scheduler-ant. xml worker 1: Worker args: -jndi. name. conn. Factory Connection. Factory -jndi. name. destination queue/ejava/examples/jms. Scheduler/request. Queue -jndi. name. DLQ queue/ejava/examples/jms. Scheduler/DLQ -name Worker 1 -max 3 -worker Worker 1 starting -Worker 1 received message #1, req=2, reply. To=QUEUE. JMS_TQ 3, delay=0 -committing session -Worker 1 received message #2, req=4, reply. To=QUEUE. JMS_TQ 3, delay=10 -committing session -Worker 1 received message #3, req=6, reply. To=QUEUE. JMS_TQ 3, delay=10 -worker Worker 1 stopping v 121128 JMS 32

JMS API v 121128 JMS Enterprise Java 33

JMS API v 121128 JMS Enterprise Java 33

 • Destination JMS API Enterprise Java – an identifier for a queue or

• Destination JMS API Enterprise Java – an identifier for a queue or topic in the provider • Connection. Factory – encapsulates a set of properties for creating connections to provider • Connection – represents a physical connection to the provider • Session – a context for sending/receiving messages for a Thread – factory for creating remaining JMS objects • Message – unit of communication • Message. Producer – used to send messages • Message. Consumer – used to receive messages • Message. Listener – optionally implemented by client to receive messages asynchronously • Exception. Listener – optionally implemented by client to receive JMSExceptions relative to the connection v 121128 JMS 34

Connection. Factory Enterprise Java • Administered Object – commonly obtained from JNDI – Parent

Connection. Factory Enterprise Java • Administered Object – commonly obtained from JNDI – Parent interface for specialized factories • Topic. Connection. Factory, Queue. Connection. Factory, XAConnection. Factory • Encapsulates a set of connection attributes set by administrator – client. Id – listen address Connection. Factory conn. Factory = (Connection. Factory)jndi. lookup(conn. Factory. JNDIName); Connection connection = null; try { connection = conn. Factory. create. Connection(); } finally { if (connection != null) { connection. close(); } v 121128 } JMS 35

Connection Enterprise Java • Client's active connection to JMS provider – typically represents an

Connection Enterprise Java • Client's active connection to JMS provider – typically represents an open tcp/ip socket to provider – allocates resources outside of client JVM • Authentication performed when created • Supports an Exception. Listener • Thread-safe object – heavyweight – no designed need for multiple connections • Parent interface for specialized factories – Topic. Connection, Queue. Connection, XAConnection • Created in stopped state – stopped – no messages being delivered – started – messages can be received • v 121128 Messages can be sent in both JMS started and stopped state 36

Session Enterprise Java • Single Threaded context for producing and consuming message Session session

Session Enterprise Java • Single Threaded context for producing and consuming message Session session = null; try { session = connection. create. Session(false, //is. Transacted Session. AUTO_ACKNOWLEDGE); //ack. Mode. . . } finally { if (session != null) { session. close(); } } • Parent interface for specialized factories – Topic. Session, Queue. Session, XASession • Typical to use single session as part of a transaction – synchronously block on receive – send result – commit • Receiving and sending on separate threads need separate sessions v 121128 JMS 37

Session (cont. ) Enterprise Java • is. Transacted – form local transaction within provider

Session (cont. ) Enterprise Java • is. Transacted – form local transaction within provider – false – session either joins JTA or no tx outside JTA session = connection. create. Session(false, //is. Transacted Session. AUTO_ACKNOWLEDGE); //ack. Mode. . . producer. send(message); //automatically committed – true – session forms its own transaction context session = connection. create. Session(true, //is. Transacted Session. AUTO_ACKNOWLEDGE); //ack. Mode. . . Message message 1 = consumer. receive(); producer. send(message 2); . . . session. commit(); //commit outstanding session messages -orsession. rollback(); //rollback outstanding session messages v 121128 JMS 38

Session (cont. ) Enterprise Java • Session retains consumed messages until acknowledged • Acknowledgement

Session (cont. ) Enterprise Java • Session retains consumed messages until acknowledged • Acknowledgement Modes session = connection. create. Session(false, //transacted Session. AUTO_ACKNOWLEDGE); //ack. Mode – AUTO_ACKNOWLEDGE • message automatically acknowledged by session when client receives (receive()) or processes (on. Message) message – CLIENT_ACKNOWLEDGE • messages are manually acknowledged • any acknowledged message acknowledges all prior messages consumed message. acknowledge(); //manually ack this and all //preceding messages – DUPS_OK_ACKNOWLEDGE • similar to AUTO_ACKNOWLEDGE • session lazily acknowledges messages • can result in duplicate messages v 121128 JMS 39

Session (cont. ) Enterprise Java • Factory for Temporary. Topics and Temporary. Queues Topic

Session (cont. ) Enterprise Java • Factory for Temporary. Topics and Temporary. Queues Topic temp. Topic = session. create. Temporary. Topic(); Queue temp. Queue = session. create. Temporary. Queue(); • May optionally create queues and topics – not portable Topic topic = session. create. Topic(topic. Name); Queue queue = session. create. Queue(queue. Name); v 121128 JMS 40

Session (cont. ) Enterprise Java • Factory for Queue. Browsers – look at messages

Session (cont. ) Enterprise Java • Factory for Queue. Browsers – look at messages on queue without removing them Queue. Browser qbrowser = session. create. Browser((Queue)destination); for (Enumeration e = qbrowser. get. Enumeration(); e. has. More. Elements(); ) { Message m = (Message) e. next. Element(); log. debug("browsing message=" + m. get. JMSMessage. ID()); } – changes in queue between getting enumeration and accessing message undefined by specification v 121128 JMS 41

Session (cont. ) Enterprise Java • Factory for provider-specific messages Message message = session.

Session (cont. ) Enterprise Java • Factory for provider-specific messages Message message = session. create. Message(); <T>Message message = session. create<T>Message(); • Factory for Message. Producers and Message. Consumers Message. Producer producer = session. create. Producer(destination); producer. send(message); Message. Consumer consumer = session. create. Consumer(destination); Message message = consumer. receive(); v 121128 JMS 42

Message. Consumer Enterprise Java • Used to receive messages from a destination • Parent

Message. Consumer Enterprise Java • Used to receive messages from a destination • Parent interface for specialized message consumers – Topic. Subscriber – Queue. Receiver • Two approaches to receive messages – Client may poll message consumer for messages – Client have messages asynchronously delivered as they arrive v 121128 JMS 43

Message. Consumer (cont. ) Enterprise Java • Client may poll message consumer for messages

Message. Consumer (cont. ) Enterprise Java • Client may poll message consumer for messages – Message. Consumer. receive(timeout) : Message private class Sync. Client implements My. Client { private Message. Consumer consumer; public Sync. Client(Message. Consumer consumer) { this. consumer = consumer; } public int get. Count() { return count; } public Message get. Message() throws JMSException { Message message=consumer. receive. No. Wait(); return message; } }. . . Message. Consumer sync. Consumer = session. create. Consumer(destination); Sync. Client sync. Client = new Sync. Client(sync. Consumer); Message message = sync. Client. get. Message(); v 121128 JMS 44

Message. Consumer (cont. ) Enterprise Java • Client may implement an interface to have

Message. Consumer (cont. ) Enterprise Java • Client may implement an interface to have message consumer asynchronously deliver them as they arrive – Message. Listener. on. Message(Message message) – callback may not throw an exception . . . private class Async. Client implements Message. Listener { Linked. List<Message> messages = new Linked. List<Message>(); public void on. Message(Message message) { try { messages. add(message); //process message } catch (JMSException ex) { log. fatal("error handling message", ex); } } public Message get. Message() { return (messages. is. Empty() ? null : messages. remove()); } } Message. Consumer async. Consumer = session. create. Consumer(destination); Async. Client async. Client = new Async. Client(); async. Consumer. set. Message. Listener(async. Client); Message message = async. Client. get. Message(); v 121128 JMS 45

Message. Consumer (cont. ) Enterprise Java • Selectors can be applied to reduce noise

Message. Consumer (cont. ) Enterprise Java • Selectors can be applied to reduce noise to Message. Consumer – sql-like selector based on JMS and user properties – null or empty string equivalent to no selector String selector 1 = "level in ('warn', 'fatal')"; async. Consumer = session. create. Consumer(destination, selector 1); Async. Client async. Client = new Async. Client(); async. Consumer. set. Message. Listener(async. Client); . . . String selector 2 = "level in ('info', 'warn', 'fatal')"; sync. Consumer = session. create. Consumer(destination, selector 2); Sync. Client sync. Client = new Sync. Client(sync. Consumer); . . . String levels[] = {"debug", "info", "warn", "fatal"}; Message. Producer producer = session. create. Producer(destination); Message message = session. create. Message(); for (String level : levels) { message. set. String. Property("level", level); producer. send(message); }. . . //for Topics assert. Equals(2, async. Client. get. Count()); assert. Equals(3, sync. Client. get. Count()); v 121128 JMS 46

Message. Consumer (cont. ) Enterprise Java • Durable subscriptions can be used for Topic.

Message. Consumer (cont. ) Enterprise Java • Durable subscriptions can be used for Topic. Subscribers – messages stored while Topic. Subscriber not physically connected – consumes resources on server Message. Consumer non. Durable. Consumer = session. create. Consumer(destination); . . . non. Durable. Consumer. receive(); //won't receive messages sent while //physically disconnected //the Connection. client. ID is needed for Durable Subscriptions connection. set. Client. ID("test. Durable. Subscription"); . . . Message. Consumer durable. Consumer = session. create. Durable. Subscriber((Topic)destination, "async 1"); . . . durable. Consumer. receive(); //will receive messages not yet consumed //that have been sent after initial //registration v 121128 JMS 47

Message. Producer Enterprise Java • Used to send messages to a destination • Parent

Message. Producer Enterprise Java • Used to send messages to a destination • Parent interface for specialized message consumers – Topic. Publisher – Queue. Sender • Created from Session Message. Producer producer = session. create. Producer(destination); – destination can be null • Can set other defaults with Message. Producer properties – delivery. Mode – priority – time. To. Live • Can set certain optimizations – disable. Timestamp – disable. Message. ID v 121128 JMS 48

Message. Producer (cont. ) Enterprise Java • Priority – int value (0 lowest, 9

Message. Producer (cont. ) Enterprise Java • Priority – int value (0 lowest, 9 highest) • 0 -4 normal, 4 default, and 5 -9 expedited int priorities[] = {9, 0, 8, 1, 7, 2, 6, 3, 6, 4, 5}; for (int i=0; i<msg. Count; i++) { for (int priority : priorities) { producer. set. Priority(priority); producer. send(message); } -on. Message -on. Message v 121128 received received received (1): ID: 842 -11642396791971, priority=9 (2): ID: 842 -11642396792013, priority=8 (3): ID: 842 -11642396792035, priority=7 (4): ID: 842 -11642396792057, priority=6 (5): ID: 842 -11642396792129, priority=6 (6): ID: 842 -116423967921511, priority=5 (7): ID: 842 -116423967921410, priority=4 (8): ID: 842 -11642396792118, priority=3 (9): ID: 842 -11642396792046, priority=2 (10): ID: 842 -11642396792024, priority=1 (11): ID: 842 -11642396792002, priority=0 JMS 49

Message. Producer (cont. ) Enterprise Java • Priority – can alternately be specified on

Message. Producer (cont. ) Enterprise Java • Priority – can alternately be specified on send producer. send(message, Message. DEFAULT_DELIVERY_MODE, priority, Message. DEFAULT_TIME_TO_LIVE); -on. Message -on. Message v 121128 received received received (1): ID: 844 -11642400027451, priority=9 (2): ID: 844 -11642400027533, priority=8 (3): ID: 844 -11642400027605, priority=7 (4): ID: 844 -11642400027707, priority=6 (5): ID: 844 -11642400027789, priority=6 (6): ID: 844 -116424000283911, priority=5 (7): ID: 844 -116424000278110, priority=4 (8): ID: 844 -11642400027748, priority=3 (9): ID: 844 -11642400027676, priority=2 (10): ID: 844 -11642400027574, priority=1 (11): ID: 844 -11642400027482, priority=0 JMS 50

Message. Producer (cont. ) Enterprise Java • Priority – Message. Producer, not message, priority

Message. Producer (cont. ) Enterprise Java • Priority – Message. Producer, not message, priority used message. set. JMSPriority(priority); producer. send(message); -sent -sent -sent v 121128 (0)msg. Id=ID: 847 -11642402118871, priority=4 (0)msg. Id=ID: 847 -11642402118902, priority=4 (0)msg. Id=ID: 847 -11642402118933, priority=4 (0)msg. Id=ID: 847 -11642402118954, priority=4 (0)msg. Id=ID: 847 -11642402118985, priority=4 (0)msg. Id=ID: 847 -11642402119156, priority=4 (0)msg. Id=ID: 847 -11642402119217, priority=4 (0)msg. Id=ID: 847 -11642402119238, priority=4 (0)msg. Id=ID: 847 -11642402119269, priority=4 (0)msg. Id=ID: 847 -116424021192910, priority=4 (0)msg. Id=ID: 847 -116424021193111, priority=4 JMS 51

Message. Producer (cont. ) Enterprise Java • Time To Live (TTL) – Used to

Message. Producer (cont. ) Enterprise Java • Time To Live (TTL) – Used to timeout undelivered messages – 0 indicates no timeout long ttl. Msecs[] = {100, 0, 10000, 10000}; for (long ttl : ttl. Msecs) { producer. set. Time. To. Live(ttl); producer. send(message); } -sent msg. Id=ID: 863 -11642421904101, expiration=1164242190510, -sent msg. Id=ID: 863 -11642421904142, expiration=0, 0 msecs -sent msg. Id=ID: 863 -11642421904163, expiration=1164242200416, -sent msg. Id=ID: 863 -11642421904174, expiration=1164242190517, -sent msg. Id=ID: 863 -11642421904185, expiration=1164242200418, -waiting 1000 msecs for some messages to expire -on. Message received (1): ID: 863 -11642421904142, expiration=0, -on. Message received (2): ID: 863 -11642421904163, expiration=1164242200416, 8981 msecs -on. Message received (3): ID: 863 -11642421904185, expiration=1164242200418, 8976 msecs v 121128 JMS 97 msecs 10000 msecs 52

Message. Producer (cont. ) Enterprise Java • Time To Live (TTL) – can alternately

Message. Producer (cont. ) Enterprise Java • Time To Live (TTL) – can alternately specify on send producer. send(message, Message. DEFAULT_DELIVERY_MODE, Message. DEFAULT_PRIORITY, ttl); -sent msg. Id=ID: 864 -11642421925561, expiration=1164242192656, -sent msg. Id=ID: 864 -11642421925592, expiration=0, 0 msecs -sent msg. Id=ID: 864 -11642421925833, expiration=1164242202583, -sent msg. Id=ID: 864 -11642421925884, expiration=1164242192688, -sent msg. Id=ID: 864 -11642421925915, expiration=1164242202591, -waiting 1000 msecs for some messages to expire -on. Message received (1): ID: 864 -11642421925592, expiration=0, -on. Message received (2): ID: 864 -11642421925833, expiration=1164242202583, 8965 msecs -on. Message received (3): ID: 864 -11642421925915, expiration=1164242202591, 8971 msecs v 121128 JMS 99 msecs 9998 msecs 9995 msecs 0 msecs 53

Message. Producer (cont. ) Enterprise Java • Delivery Mode – pertains only to transit

Message. Producer (cont. ) Enterprise Java • Delivery Mode – pertains only to transit of message to destination – no impact on actual delivery, timeout, or storage issues – PERSISTENT • instructs provider to log message to persistent storage before completing the send • more robust, slower – NON_PERSISTENT • allows provider to buffer messages prior performing any logging to persistent storage • more efficient, faster producer. send(message, mode, Message. DEFAULT_PRIORITY, Message. DEFAULT_TIME_TO_LIVE); -total messages per test=10000 -mode: NON_PERSISTENT total=5066 msecs , ave=0. 5066 msecs -mode: PERSISTENT total=5746 msecs , ave=0. 5746 msecs v 121128 JMS 54

Messages Enterprise Java • Contents – Header • standard header fields – Properties •

Messages Enterprise Java • Contents – Header • standard header fields – Properties • application-specific properties • supports message filtering (using selectors) – Body • • • v 121128 Stream – stream of Java primitive values Map – string names and Java primitive values Text – java. lang. String body (supports XML) Object – Serializable Object body Bytes – raw byte format JMS 55

Message Header Enterprise Java • JMSMessage. ID : String – unique key – assigned

Message Header Enterprise Java • JMSMessage. ID : String – unique key – assigned a provider-supplied value on send – values start with “ID: ” – disabled with Message. Provider. set. Disable. Message. ID() – can be optionally changed by recipient • JMSTimestamp : long – time when message given to provider to be sent – assigned by during send – not actual time sent (queuing, re-transmit, etc. ) – diabled with Message. Provider. set. Disable. Timestamp() v 121128 JMS 56

Message Header (cont. ) Enterprise Java • JMSCorrelation. ID : String – links message

Message Header (cont. ) Enterprise Java • JMSCorrelation. ID : String – links message to something • another message – JMSMessage. ID value – must start with “ID: ” • processing context – application String value – must not start with “ID: ” • provider-specific legacy format value – contains raw byte[] • JMSCorrelation. IDAs. Bytes : byte[] – used only by providers with legacy correlation. ID formats – not portable v 121128 JMS 57

Message Header (cont. ) Enterprise Java • JMSReply. To : Destination – signals a

Message Header (cont. ) Enterprise Java • JMSReply. To : Destination – signals a request for a reply – sets Destination for reply • producer. send(reply. To, message, . . . ); • JMSDestination : Destination – contains the Destination messages was sent to – set during send() – received messages contain Destination sent to • JMSDelivery. Mode : int – set during send() • JMSRedelivered : boolean – an indication that message has been received, but not successfully ackowledged, before v 121128 JMS 58

Message Header (cont. ) Enterprise Java • JMSType : String – no meaning or

Message Header (cont. ) Enterprise Java • JMSType : String – no meaning or format defined by spec – spec suggests flexible use of field at deployment time to be portable across providers • JMSExpiration : long – a point in time, after which, the undelivered message may be expired from storage – calculation of the time-to-live value and GMT – assigned during send() – 0 value indicates message does not expire – spec does not define a notification of expiration (or delivery!) • JMSPriority : int – 0 (lowest) to 9 (highest) v 121128 JMS 59

Example Header Values Enterprise Java log. debug("message 2. JMSMessage. ID=" + message 2. get.

Example Header Values Enterprise Java log. debug("message 2. JMSMessage. ID=" + message 2. get. JMSMessage. ID()); log. debug("message 2. JMSTimestamp=" + message 2. get. JMSTimestamp()); try { log. debug("message 2. JMSCorrelation. IDAs. Bytes=" + message 2. get. JMSCorrelation. IDAs. Bytes()); } catch (JMSException ex) { log. debug("message 2. JMSCorrelation. IDAs. Bytes=" + ex); } log. debug("message 2. JMSCorrelation. ID=" +message 2. get. JMSCorrelation. ID()); . . . log. debug("message 2. JMSPriority=" + message 2. get. JMSPriority()); -message 2. JMSMessage. ID=ID: 154 -11643934309001 -message 2. JMSTimestamp=1164393430900 -message 2. JMSCorrelation. IDAs. Bytes=javax. jms. JMSException: JMSCorrelation. ID is a string -message 2. JMSCorrelation. ID=null -message 2. JMSReply. To=null -message 2. JMSDestination=TOPIC. ejava/jms/topic 1 -message 2. JMSDelivery. Mode=2 -message 2. JMSRedelivered=false -message 2. JMSType=null -message 2. JMSExpiration=0 -message 2. JMSPriority=4 v 121128 JMS 60

Reply. To Example: request Enterprise Java • Create a set of separate Reply. To

Reply. To Example: request Enterprise Java • Create a set of separate Reply. To queues producer = session. create. Producer(destination); Destination reply. Destinations[] = { session. create. Temporary. Queue(), . . . }; for(Destination reply. To : reply. Destinations) { reply. Consumers. add(session. create. Consumer(reply. To)); } • Send a “request” with the reply. To destination Message message = session. create. Message(); Map<String, Message> responses = new Hash. Map<String, Message>(); for(Destination reply. To : reply. Destinations) { message. set. JMSReply. To(reply. To); producer. send(message); responses. put(message. get. JMSMessage. ID(), null); } v 121128 JMS 61

Reply. To Example: reply Enterprise Java • Create reply objects public void set. Session(Session

Reply. To Example: reply Enterprise Java • Create reply objects public void set. Session(Session session) throws JMSException { producer = session. create. Producer(null); reply = session. create. Message(); } • Send reply to requested destination public void on. Message(Message message) { try { //process request Destination reply. Destination = message. get. JMSReply. To(); reply. set. JMSCorrelation. ID(message. get. JMSMessage. ID()); producer. send(reply. Destination, reply); } catch (JMSException ex) {. . . } } v 121128 JMS 62

Reply. To Example: handle response Enterprise Java • Check for replies for(int d=0; d<reply.

Reply. To Example: handle response Enterprise Java • Check for replies for(int d=0; d<reply. Destinations. length; d++) { Message m = reply. Consumers. get(d). receive. No. Wait(); if (m != null) { responses. put(message. get. JMSCorrelation. ID(), m); } } • Sample output -sent (1)msg. Id=ID: 27 -11643888726611, reply. To=QUEUE. JMS_TQ 21 -sent (2)msg. Id=ID: 27 -11643888726652, reply. To=QUEUE. JMS_TQ 22 -sent (3)msg. Id=ID: 27 -11643888726663, reply. To=QUEUE. JMS_TQ 23 -sent (4)msg. Id=ID: 27 -11643888726674, reply. To=QUEUE. JMS_TQ 24 -on. Message received (1): ID: 27 -11643888726611, reply. To=QUEUE. JMS_TQ 21 -on. Message received (2): ID: 27 -11643888726652, reply. To=QUEUE. JMS_TQ 22 -on. Message received (3): ID: 27 -11643888726663, reply. To=QUEUE. JMS_TQ 23 -on. Message received (4): ID: 27 -11643888726674, reply. To=QUEUE. JMS_TQ 24 v 121128 JMS 63

Message Properties Enterprise Java • Supports application-defined header fields • Names – String –

Message Properties Enterprise Java • Supports application-defined header fields • Names – String – cannot be null – cannot be empty strings – “JMSX” property name prefix is reserved • JMXGroup. ID • JMSXGroup. Seq – JMS_vendor_name – property prefix is reserved • Values – boolean, byte, short, int, long, float, double, String – accessed through typed setters/getters or set. Object. Property/get. Object. Property v 121128 JMS 64

Message Properties (cont. ) Enterprise Java • Names retrieved using get. Property. Names() •

Message Properties (cont. ) Enterprise Java • Names retrieved using get. Property. Names() • Read/Write by sender • Read-only by receiver – Message. clear. Properties() permits write access to property area – Header values are never read-only v 121128 JMS 65

Message Properties (cont. ) Enterprise Java • Example using Message properties Message message =

Message Properties (cont. ) Enterprise Java • Example using Message properties Message message = session. create. Message(); message. set. Boolean. Property("boolean. Property", true); message. set. Byte. Property("byte. Property", (byte)0 x 01); message. set. Double. Property("double. Property", 1. 01); message. set. Float. Property("float. Property", (float)1. 02); message. set. Int. Property("int. Property", 3); message. set. Long. Property("long. Property", 5 L); message. set. Object. Property("int. Property. As. Object", 3); message. set. Short. Property("short. Property", (short)4); message. set. String. Property("string. Property", "hello JMS world"); producer. send(message); Message message 2 = consumer. receive(1000); -message 2. byte. Property (: java. lang. Byte)=1 -message 2. long. Property (: java. lang. Long)=5 -message 2. short. Property (: java. lang. Short)=4 -message 2. double. Property (: java. lang. Double)=1. 01 -message 2. string. Property (: java. lang. String)=hello JMS world -message 2. int. Property. As. Object (: java. lang. Integer)=3 -message 2. float. Property (: java. lang. Float)=1. 02 -message 2. boolean. Property (: java. lang. Boolean)=true -message 2. int. Property (: java. lang. Integer)=3 -message 2. JMSXDelivery. Count (: java. lang. Integer)=1 v 121128 JMS 66

Message Forms Enterprise Java • Stream. Message – stream of Java primitive values •

Message Forms Enterprise Java • Stream. Message – stream of Java primitive values • Map. Message – string names and Java primitive values • Text. Message – java. lang. String body (supports XML) • Object. Message – Serializable Object body • Bytes. Message – raw byte format • Message – only contains JMS Header and application properties v 121128 JMS 67

Example Message. Test Framework Enterprise Java private class Replier implements Message. Listener { private

Example Message. Test Framework Enterprise Java private class Replier implements Message. Listener { private Message. Producer producer; public void on. Message(Message request) { try { Message reply = null; if (request instanceof Stream. Message) { reply = get. Reply((Stream. Message)request); } else. . . reply. set. JMSCorrelation. ID( request. get. JMSMessage. ID()); producer. send(reply. Destination, reply); } catch (Exception ex) { log. fatal("error handling message", ex); } } protected Message get. Reply(<T>Message request) throws JMSException {. . . //detailed on following slides return reply; } } v 121128 JMS 68

Stream. Message Enterprise Java • used to send a stream of Java primitive values

Stream. Message Enterprise Java • used to send a stream of Java primitive values – filled and read sequentially • based on java. io. Data. Input/Output. Stream interfaces • values can be accessed explicitly – stream. Message. write. Int(3) – int value = stream. Message. read. Int(); • values can be accessed generically – stream. Message. write. Object(new Integer(3)); – Object value = stream. Message. read. Object(); • write-only mode – first created – clear. Body() called • used by sender to re-use a previously sent message • read-only mode – when received – when reset() called • used to reset the stream to the first byte v 121128 JMS 69

Stream. Message Example Enterprise Java • Example request Stream. Message request = session. create.

Stream. Message Example Enterprise Java • Example request Stream. Message request = session. create. Stream. Message(); request. write. String("add"); request. write. Int(2); request. write. Int(3); request. set. JMSReply. To(reply. Destination); producer. send(request); Stream. Message response = (Stream. Message)reply. Consumer. receive(); int result = response. read. Int(); assert. Equals("wrong answer: " + result, 5, result); • Example reply String operator = request. read. String(); int operand 1 = request. read. Int(); int operand 2 = request. read. Int(); int result = ("add". equals(operator) ? operand 1 + operand 2 : -1); Stream. Message reply = session. create. Stream. Message(); reply. write. Int(result); v 121128 JMS 70

Map. Message Enterprise Java • Used to send name/primitive value pairs – name –

Map. Message Enterprise Java • Used to send name/primitive value pairs – name – String – value – Java primitive • Values can be accessed explicitly – map. Message. set. Int(“name”, 3); – int value = map. Message. get. Int(“name”); • Values can be accessed generically – map. Message. set. Object(“name”, new Integer(3)); – Object value = map. Message. get. Object(“name”); • read/write mode – when created – clear. Body() called • read-only mode – when received v 121128 JMS 71

Map. Message Example Enterprise Java • Example request Map. Message request = session. create.

Map. Message Example Enterprise Java • Example request Map. Message request = session. create. Map. Message(); request. set. String("operator", "add"); request. set. Int("operand 1", 2); request. set. Int("operand 2", 3); request. set. JMSReply. To(reply. Destination); producer. send(request); Map. Message response = (Map. Message)reply. Consumer. receive(); int result = response. get. Int("result"); assert. Equals("wrong answer: " + result, 5, result); • Example reply String operator = request. get. String("operator"); int operand 1 = request. get. Int("operand 1"); int operand 2 = request. get. Int("operand 2"); int result = ("add". equals(operator) ? operand 1 + operand 2 : -1); Map. Message reply = session. create. Map. Message(); reply. set. Int("result", result); v 121128 JMS 72

Text. Message Enterprise Java • Sends a String message • Used for text. based

Text. Message Enterprise Java • Sends a String message • Used for text. based messages – XML – Property lists • Only a single value, only accessed as String – text. Message. set. Text(“hello world”); – String value = text. Message. get. Text(); • read/write mode – when created – clear. Body() called • read-only – when received v 121128 JMS 73

Text. Message Example Enterprise Java • Example Text. Message request = session. create. Text.

Text. Message Example Enterprise Java • Example Text. Message request = session. create. Text. Message(); Properties props = new Properties(); props. put("operator", "add"); props. put("operand 1", new Integer(2). to. String()); props. put("operand 2", new Integer(3). to. String()); String. Writer body. Text = new String. Writer(); props. list(new Print. Writer(body. Text)); request. set. Text(body. Text. to. String()); request. set. JMSReply. To(reply. Destination); producer. send(request); Text. Message response = (Text. Message)reply. Consumer. receive(); String result. Str = response. get. Text(); int result = Integer. parse. Int(result. Str); assert. Equals("wrong answer: " + result, 5, result); v 121128 JMS 74

Text. Message Example Enterprise Java • Example Text. Message reply Properties props = new

Text. Message Example Enterprise Java • Example Text. Message reply Properties props = new Properties(); props. load(new Byte. Array. Input. Stream(request. get. Text(). get. Bytes())); String operator = props. get. Property("operator"); int operand 1 = Integer. parse. Int(props. get. Property("operand 1")); int operand 2 = Integer. parse. Int(props. get. Property("operand 2")); int result = ("add". equals(operator) ? operand 1 + operand 2 : -1); Text. Message reply = session. create. Text. Message(); reply. set. Text(new Integer(result). to. String()); v 121128 JMS 75

Object. Message Enterprise Java • Sends a Serializable Object • Only a single value,

Object. Message Enterprise Java • Sends a Serializable Object • Only a single value, accessed as Serializable – object. Message. set. Object(new Integer(3)); – Object value = (Object)object. Message. get. Object(); • read/write – when created – clear. Body() called • read-only – when received v 121128 JMS 76

Object. Message Example Enterprise Java • Example Object. Message request = session. create. Object.

Object. Message Example Enterprise Java • Example Object. Message request = session. create. Object. Message(); Map<String, Serializable> body = new Hash. Map<String, Serializable>(); body. put("operator", "add"); body. put("operand 1", new My. Integer(2)); //use a custom class as an body. put("operand 2", new My. Integer(3)); //example of serializable request. set. Object((Serializable)body); request. set. JMSReply. To(reply. Destination); producer. send(request); Object. Message response = (Object. Message)reply. Consumer. receive(); int result = ((My. Integer)response. get. Object()). get. Value(); assert. Equals("wrong answer: " + result, 5, result); v 121128 JMS 77

Object. Message Example Enterprise Java • Example Object. Message reply Map<String, Object> body =

Object. Message Example Enterprise Java • Example Object. Message reply Map<String, Object> body = (Map<String, Object>)request. get. Object(); String operator = (String)body. get("operator"); int operand 1 = ((My. Integer)body. get("operand 1")). get. Value(); int operand 2 = ((My. Integer)body. get("operand 2")). get. Value(); int result = ("add". equals(operator) ? operand 1 + operand 2 : -1); Object. Message reply = session. create. Object. Message(); reply. set. Object(new My. Integer(result)); • Example Serializable Application Class used //this class is used to provide an example of a custom class sent //within a serializable payload private class My. Integer implements Serializable { private static final long serial. Version. UID = 1 L; private int value; public My. Integer(int value) { this. value = value; } public int get. Value() { return value; } } v 121128 JMS 78

Bytes. Message Enterprise Java • Send a stream of uninterpreted bytes – based on

Bytes. Message Enterprise Java • Send a stream of uninterpreted bytes – based on java. io. Data. Input/Output. Stream • intended for messages with legacy formats – available for use for messages with binary content – legacy messages may not permit • use of full set of JMS Headers • any JMS Properties • values can be accessed explicitly – bytes. Message. write. Int(3); – int value = bytes. Message. read. Int(); • values can be written (but not read) generically – bytes. Message. write. Object(new Integer(3)); • write-only mode – when created – clear. Body() called • read-only – when received v 121128 – reset() called JMS 79

Bytes. Message Example Enterprise Java • Example Bytes. Message request Byte. Array. Output. Stream

Bytes. Message Example Enterprise Java • Example Bytes. Message request Byte. Array. Output. Stream bos = new Byte. Array. Output. Stream(); bos. write("add". get. Bytes()); bos. write(2); bos. write(3); Bytes. Message request = session. create. Bytes. Message(); request. write. Bytes(bos. to. Byte. Array()); request. set. JMSReply. To(reply. Destination); producer. send(request); Bytes. Message response = (Bytes. Message)reply. Consumer. receive(); int result = response. read. Int(); assert. Equals("wrong answer: " + result, 5, result); v 121128 JMS 80

Bytes. Message Example Enterprise Java • Example Bytes. Message reply log. debug("body=" + request.

Bytes. Message Example Enterprise Java • Example Bytes. Message reply log. debug("body=" + request. get. Body. Length() + " bytes"); byte buffer[] = new byte[10]; request. read. Bytes(buffer, 3); String operator = new String(buffer); int operand 1 = request. read. Byte(); int operand 2 = request. read. Byte(); int result = (operator. starts. With("add") ? operand 1 + operand 2 : -1); Bytes. Message reply = session. create. Bytes. Message(); reply. write. Int(result); v 121128 JMS 81

(Simple) Message Example Enterprise Java • Example request Message request = session. create. Message();

(Simple) Message Example Enterprise Java • Example request Message request = session. create. Message(); request. set. String. Property("operator", "add"); request. set. Int. Property("operand 1", 2); request. set. Int. Property("operand 2", 3); request. set. JMSReply. To(reply. Destination); producer. send(request); Message response = reply. Consumer. receive(); int result = response. get. Int. Property("result"); assert. Equals("wrong answer: " + result, 5, result); • Example reply String operator = request. get. String. Property("operator"); int operand 1 = request. get. Int. Property("operand 1"); int operand 2 = request. get. Int. Property("operand 2"); int result = ("add". equals(operator) ? operand 1 + operand 2 : -1); Message reply = session. create. Message(); reply. set. Int. Property("result", result); v 121128 JMS 82

Queue/Topic Requestor Enterprise Java • Meant to simplify request/reply scenarios – Too simple for

Queue/Topic Requestor Enterprise Java • Meant to simplify request/reply scenarios – Too simple for realistic use! • no timeouts • no mixing of request/reply destination types – users encouraged to create more robust implementations • Helper is provided – a non-transacted session – destination • Helper creates – temporary destination • Example Queue. Request requestor = new Queue. Requestor(session, target. Queue); Message reply = resquestor(request); Topic. Request requestor = new Topic. Requestor(session, target. Topic); Message reply = resquestor(request); v 121128 JMS 83

Building JMS Modules v 121128 JMS Enterprise Java 84

Building JMS Modules v 121128 JMS Enterprise Java 84

Dependencies Enterprise Java • JMS API <dependency> <group. Id>javax. jms</group. Id> <artifact. Id>jms</artifact. Id>

Dependencies Enterprise Java • JMS API <dependency> <group. Id>javax. jms</group. Id> <artifact. Id>jms</artifact. Id> <scope>provided</scope> </dependency> • JMS Provider (Hornet. Q) Driver <dependency> <group. Id>org. hornetq</group. Id> <artifact. Id>hornetq-jms-client</artifact. Id> <scope>test</scope> </dependency> <group. Id>org. hornetq</group. Id> <artifact. Id>hornetq-core</artifact. Id> <scope>test</scope> </dependency> <group. Id>org. jboss. netty</group. Id> <artifact. Id>netty</artifact. Id> <scope>test</scope> </dependency> • JBoss RMI Dependencies <dependency> <group. Id>ejava. common</group. Id> <artifact. Id>jboss-rmi-client</artifact. Id> <type>pom</type> <scope>test</scope> </dependency> v 121128 JMS 85

Enterprise Java JSE Classpath Option #1: build-classpath • Use dependency-plugin to build classpath to

Enterprise Java JSE Classpath Option #1: build-classpath • Use dependency-plugin to build classpath to M 2_REPO <plugin> <group. Id>org. apache. maven. plugins</group. Id> <artifact. Id>maven-dependency-plugin</artifact. Id> <executions> <execution> <phase>package</phase> <goals> <goal>build-classpath</goal> </goals> </executions> <configuration> <output. File>target/test-classes/dependency-classpath</output. File> </configuration> </plugin> $ cat target/test-classes/dependency-classpath /home/jcstaff/. m 2/repository/javax/jms/1. 1/jms-1. 1. jar: /home/jcstaff/. m 2/repository/commonslogging/commons-logging/1. 1. 1/commons-logging- … v 121128 JMS 86

Enterprise Java JSE Classpath Option #2: copy-dependencies • Use dependency-plugin to build classpath to

Enterprise Java JSE Classpath Option #2: copy-dependencies • Use dependency-plugin to build classpath to M 2_REPO <plugin> <group. Id>org. apache. maven. plugins</group. Id> <artifact. Id>maven-dependency-plugin</artifact. Id> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </executions> <configuration> <output. File>target/test-classes/dependency-classpath</output. File> </configuration> </plugin> $ ls target/dependency activation-1. 1. 1. jar commons-logging-1. 1. 1. jar dtdparser 121 -1. 2. 1. jar v 121128 jboss-as-process-controller-7. 1. 1. Final. jar jboss-remoting-3. 2. 3. GA. jar jboss-as-protocol-7. 1. 1. Final. jar jboss-rmi-client-3. 0. 2012. 2 -20121125. 211007 -22. pom jboss-as-remoting-7. 1. 1. Final. jar jboss-sasl-1. 0. 0. Final. jar JMS 87

Setting JSE Classpath Enterprise Java • Account for either – Long Classpath reference into

Setting JSE Classpath Enterprise Java • Account for either – Long Classpath reference into M 2_REPO • Very large classpath – Directory Classpath • Many MB in dependency copies <project name="jms. Scheduler" basedir=". . "> <property file="test-classes/${ant. project. name}. properties"/> <loadfile property="dependency-classpath" src. File="test-classes/dependency-classpath" failonerror="false"/> <path id="demo. classpath"> <pathelement path="test-classes"/> <pathelement path="classes"/> <fileset dir=". " includes="dependency/*. jar"/> <pathelement path="${dependency-classpath}"/> </path> v 121128 JMS 88

Summary Enterprise Java • Messaging Overview – decouples Producer from Consumer • JMS Overview

Summary Enterprise Java • Messaging Overview – decouples Producer from Consumer • JMS Overview – Java API for interfacing with enterprise messaging providers • JMS Examples – defining destinations – publish/subscribe – request/reply queuing – access controls – transactional receive/send – DLQ • JMS API Detail – see JMS Javadoc v 121128 JMS 89

References Enterprise Java • Java Messaging Service API – http: //java. sun. com/javaee/5/docs/api/javax/jms/packagesummary. html

References Enterprise Java • Java Messaging Service API – http: //java. sun. com/javaee/5/docs/api/javax/jms/packagesummary. html • “Enterprise Java. Beans 3. 0, 5 th Edition”; Burke & Monsen-Haefel; ISBN 0 -596 -00978 -X; O'Reilly v 121128 JMS 90