Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's up with JMS 2.1 @ JavaLand 2016

What's up with JMS 2.1 @ JavaLand 2016

The Java Message Service Specification (JMS) got a major overhaul in Java EE 7 as JMS 2.0. In JSR 368 (JMS 2.1) this work continues.

This session will present the current status of the work with this JSR and how you as a community member may contribute. And, of course, there will also be code samples of new and improved features.

ivargrimstad

March 08, 2016
Tweet

More Decks by ivargrimstad

Other Decks in Programming

Transcript

  1. @ivar_grimstad JMS 2.1 - JavaLand 2016 What’s up with JMS

    2.1? Ivar Grimstad Principal Consultant, Cybercom Sweden JCP Expert Group Member (JSRs 368, 371, 375) JSR 368
  2. @ivar_grimstad JMS 2.1 - JavaLand 2016 Stage Initial Plan Current

    Plan Actual JSR Approval Sep 2014 Sep 2014 EG Formation Q3 (Sep) 2014 Dec 2014 EDR 1 Oct 2015 EDR 2 Q1 (Mar) 2015 Q4 (Dec) 2015 Public Review Q3 (Sep) 2015 Q1 (Mar) 2016 Proposed Final Draft Q4 (Dec) 2015 Q3 (Sep) 2016 Final Release Q3 (Sep) 2016 H1 (Jun) 2017 ✔ ?
  3. @ivar_grimstad JMS 2.1 - JavaLand 2016 JMS 1.1 @Resource(lookup =

    "jms/orderQueue") private Queue orderQueue; @Resource(lookup = “jms/myConnectionFactory") private ConnectionFactory connectionFactory; public void sendMessageEE6(String body) { Connection connection = null; try { connection = connectionFactory.createConnection();
 Session session = connection.createSession(true, Session.SESSION_TRANSACTED); MessageProducer messageProducer = session.createProducer(orderQueue); TextMessage textMessage = session.createTextMessage(body); messageProducer.send(textMessage); } catch (JMSException e) { // Handle exceptions } finally { try { connection.close(); } catch (JMSException e) { // Handle exception in close() } } }
  4. @ivar_grimstad JMS 2.1 - JavaLand 2016 JMS 2.0 @Resource(lookup =

    "jms/orderQueue") private Queue orderQueue; @Resource(lookup = “jms/myConnectionFactory") private ConnectionFactory connectionFactory; public void sendMessageEE7(String body) { try (JMSContext context = connectionFactory.createContext()){ context.createProducer().send(orderQueue, body); } catch (JMSRuntimeException e) { // Handle exceptions } }
  5. @ivar_grimstad JMS 2.1 - JavaLand 2016 JMS 2.0 @Resource(lookup =

    "jms/orderQueue") private Queue orderQueue; @Inject @JMSConnectionFactory("jms/myConnectionFactory") private JMSContext context; public void sendMessageEE7(String body) { try { context.createProducer().send(orderQueue, body); } catch (JMSRuntimeException e) { // Handle exceptions } }
  6. @ivar_grimstad JMS 2.1 - JavaLand 2016 Flexible MDBs (EE) CDI

    beans as Listeners Batch Delivery Acknowledgment Modes setMessageListener (EE) create Connection factory (SE) create Queue/Topic (SE) Repeatable Annotations Redelivery configuration (EE) JMS 2.1
  7. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = "java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } }
  8. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = "java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } } Verbose, generic annotations
  9. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = "java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } } Key-Value pairs
  10. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = "java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } } Must implement javax.jms.MessageListener
  11. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = "java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } } Fixed MDB Lifecycle
  12. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = “java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { String messageText = textMessage.getText(); // process message text } catch (JMSException e) { // exception handling } } } Verbose, generic annotations Key-Value pairs Must implement javax.jms.MessageListener Fixed MDB Lifecycle
  13. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven(activationConfig = { @ActivationConfigProperty(

    propertyName = "destinationLookup", propertyValue = “java:global/queueName"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MyMDB implements MessageListener { public void onMessage(Message message) { // handle message } } QueueListener
  14. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    implements MessageListener { public void onMessage(Message message) { // handle message } } QueueListener
  15. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    implements MessageListener { public void onMessage(Message message) { // handle message } } QueueListener
  16. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { public void onMessage(Message message) { // handle message } } QueueListener
  17. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { public void myListenerCallback(Message message) { // handle message } } QueueListener
  18. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { // handle message } } QueueListener
  19. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @TopicListener("java:global/topicName") public void myListenerCallback(Message message) { // handle message } } TopicListener
  20. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @TopicListener("java:global/topicName") @DurableSubscription @SubscriptionName("mySubName") @ClientId("myClientId") public void myListenerCallback(Message message) { // handle message } } TopicListener
  21. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { // handle message } } Message Types
  22. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(TextMessage textMessage) { // handle message } } Message Types
  23. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(String messageText) { // handle message } } Message Types <T> T getBody(Class<T> c) throws JMSException
  24. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(String messageText, @MessageHeader(Header.JMSCorrelationID) String id) { // handle message } } Message Headers
  25. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") public void myListenerCallback(String messageText, @MessageHeader(Header.JMSCorrelationID) String id, @MessageProperty("price") long price) { // handle message } } Message Properties
  26. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName1") public void myListenerCallback(Message message) { // handle message from queue 1 } @QueueListener("java:global/queueName2") public void myListenerCallback(Message message) { // handle message from queue 2 } } Multiple Callback Methods
  27. @ivar_grimstad JMS 2.1 - JavaLand 2016 @MessageDriven public class MyMDB

    { @QueueListener("java:global/queueName") @ListenerProperty("reconnectAttempts", 10) @ListenerProperty("reconnectInterval", 30000) public void myListenerCallback(Message message) { // handle message } } Proprietary Listener Properties
  28. @ivar_grimstad JMS 2.1 - JavaLand 2016 CDI Events @Inject @SomeQualifier

    private Event<MyObject> eventFirer; void fireMyEvent(){ MyObject myObj = ... eventFirer.fire(myObj); } public void myObserverMethod(@Observes @SomeQualifier MyObject myObj){ }
  29. @ivar_grimstad JMS 2.1 - JavaLand 2016 CDI Observer @Dependent public

    class MyEventObserver { public void myObserverMethod(@Observes @SomeQualifier MyObject myObj) { } }
  30. @ivar_grimstad JMS 2.1 - JavaLand 2016 Queue or Topic JMS

    Consumer Listener Bean @Dependent public class MyBean { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } } Event Style
  31. @ivar_grimstad JMS 2.1 - JavaLand 2016 Concurrency? @Dependent public class

    MyBean { @MaxInstances(10) @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } }
  32. @ivar_grimstad JMS 2.1 - JavaLand 2016 Queue or JMS Consumer

    JMS Consumer JMS Consumer Listener Bean Listener Bean Listener Bean Alternative Approach
  33. @ivar_grimstad JMS 2.1 - JavaLand 2016 @Dependent public class MyBean

    { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } } @WebServlet("/myServlet") public class MyServlet extends HttpServlet { @Inject private MyBean; public void doGet(…) { } Alternative Approach
  34. @ivar_grimstad JMS 2.1 - JavaLand 2016 Concurrency? @Dependent public class

    MyBean { @MaxInstances(10) @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } public int getNumMessages(){ // return count of msg } }
  35. @ivar_grimstad JMS 2.1 - JavaLand 2016 Event-style Alternative Listener bean

    is not injected Listener bean is injected Follows life cycle of parent One JMS Consumer per class Created on application start Closed on application stop One JMS Consumer per instance created when bean is created closed when bean is destroyed New bean for each message created when message arrives destroyed after callback returns Same bean for each message created with parent destroyed with parent Comparison
  36. @ivar_grimstad JMS 2.1 - JavaLand 2016 @RequestScoped CDI Observer @RequestScoped


    public class MyEventObserver { public void myObserverMethod(@Observes @SomeQualifier MyObject myObj) { } }
  37. @ivar_grimstad JMS 2.1 - JavaLand 2016 @RequestScoped JMS Listener @RequestScoped


    public class MyAppScopedBean { @JMSQueueListener(destinationLookup="myQueue") public void callMe(Message message) { // increment count of messages ... } public int getNumMessages() { // return count of messages } }
  38. @ivar_grimstad JMS 2.1 - JavaLand 2016 @ApplicationScoped JMS Listener @ApplicationScoped


    public class MyAppScopedBean { @JMSQueueListener(destinationLookup=“myQueue”) public void callMe(Message message) { // increment count of messages ... } public int getNumMessages() { // return count of messages } }
  39. @ivar_grimstad JMS 2.1 - JavaLand 2016 Threading? @ApplicationScoped
 public class

    MyAppScopedBean { @MaxThreads(10) @JMSQueueListener(destinationLookup="myQueue") public void callMe(Message message) { // increment count of messages ... } public int getNumMessages() { // return count of messages } }
  40. @ivar_grimstad JMS 2.1 - JavaLand 2016 Event Style Alternative Dependent

    Scoped Application Scoped Other Scopes ✔ ✔ ✔ ? ? ?
  41. @ivar_grimstad JMS 2.1 - JavaLand 2016 Batch Message Delivery Callback

    method with array of messages Enables multiple messages per transaction New annotation @Batch to configure
  42. @ivar_grimstad JMS 2.1 - JavaLand 2016 New Annotation: @Batch @MessageDriven

    public class MyMDB { @QueueListener("java:global/queueName") public void myListenerCallback( @Batch(batchSize=10, batchTimeout=1000) Message[] messages) { } }
  43. @ivar_grimstad JMS 2.1 - JavaLand 2016 Java EE 7 @JMSDestinationDefinitions(

    { @JMSDestinationDefinition( name="java:app/MyJMSQueue", interfaceName="javax.jms.Queue", destinationName="myQueue1"), @JMSDestinationDefinition( name="java:app/MyJMSQueue", interfaceName="javax.jms.Queue", destinationName="myQueue2") })
  44. @ivar_grimstad JMS 2.1 - JavaLand 2016 Java EE 8 @JMSDestinationDefinition(

    name="java:app/MyJMSQueue", interfaceName="javax.jms.Queue", destinationName="myQueue1") @JMSDestinationDefinition( name="java:app/MyJMSQueue", interfaceName="javax.jms.Queue", destinationName="myQueue2")
  45. @ivar_grimstad JMS 2.1 - JavaLand 2016 Flexible MDBs (EE) CDI

    beans as Listeners Batch Delivery Acknowledgment Modes setMessageListener (EE) create Connection factory (SE) create Queue/Topic (SE) Repeatable Annotations Redelivery configuration (EE)
  46. @ivar_grimstad JMS 2.1 - JavaLand 2016 Flexible MDBs @MessageDriven public

    class MyMDB { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } }
  47. @ivar_grimstad JMS 2.1 - JavaLand 2016 CDI Listeners public class

    MyBean { @QueueListener("java:global/queueName") public void myListenerCallback(Message message) { } }
  48. @ivar_grimstad JMS 2.1 - JavaLand 2016 Stage Initial Plan Current

    Plan Actual JSR Approval Sep 2014 Sep 2014 EG Formation Q3 (Sep) 2014 Dec 2014 EDR 1 Oct 2015 EDR 2 Q1 (Mar) 2015 Q4 (Dec) 2015 Public Review Q3 (Sep) 2015 Q1 (Mar) 2016 Proposed Final Draft Q4 (Dec) 2015 Q3 (Sep) 2016 Final Release Q3 (Sep) 2016 H1 (Jun) 2017 ✔ ?
  49. @ivar_grimstad JMS 2.1 - JavaLand 2016 Official Project Page https://jms-spec.java.net

    GitHub Playground https://github.com/jms-spec Twitter @jms_spec