Giter Club home page Giter Club logo

gs-messaging-jms's Introduction

This guide walks you through the process of publishing and subscribing to messages using a JMS broker.

What You Will build

You will build an application that uses Spring’s JmsTemplate to post a single message and subscribes to it with a @JmsListener annotated method of a managed bean.

Starting with Spring Initializr

You can use this pre-initialized project and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.

To manually initialize the project:

  1. Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you.

  2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.

  3. Click Dependencies and select Spring for Apache ActiveMQ Artemis.

  4. Click Generate.

  5. Download the resulting ZIP file, which is an archive of an application that is configured with your choices.

Note
If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
Note
You can also fork the project from Github and open it in your IDE or other editor.

Create a Message Receiver

Spring provides the means to publish messages to any POJO (Plain Old Java Object).

This guide describes how to send a message out over a JMS message broker. To start things off, create a simple POJO that embodies the details of an email message. Note that we are not sending an email message. We send the details from one place to another about WHAT to send in a message.

src/main/java/hello/Email.java

link:complete/src/main/java/hello/Email.java[role=include]

This POJO is quite simple, containing two fields (to and body), along with the presumed set of getters and setters.

From here, you can define a message receiver:

src/main/java/hello/Receiver.java

link:complete/src/main/java/hello/Receiver.java[role=include]

Receiver is also known as a message-driven POJO. As the code shows, there is no need to implement any particular interface or for the method to have any particular name. Besides, the method may have a flexible signature. Note, in particular, that this class has no import of the JMS API.

The JmsListener annotation defines the name of the Destination that this method should listen to and the reference to the JmsListenerContainerFactory to use to create the underlying message listener container. Strictly speaking, that last attribute is not necessary unless you need to customize the way the container is built, as Spring Boot registers a default factory if necessary.

The reference documentation covers this in more detail.

Send and receive JMS messages with Spring

Next, wire up a sender and a receiver.

src/main/java/hello/Application.java

link:complete/src/main/java/hello/Application.java[role=include]

For clarity, we have also defined a myFactory bean that is referenced in the JmsListener annotation of the receiver. Because we use the DefaultJmsListenerContainerFactoryConfigurer infrastructure provided by Spring Boot, that JmsMessageListenerContainer is identical to the one that Spring Boot creates by default.

The default MessageConverter can convert only basic types (such as String, Map, Serializable), and our Email is not Serializable on purpose. We want to use Jackson and serialize the content to JSON in text format (that is, as a TextMessage). Spring Boot detects the presence of a MessageConverter and associates it to both the default JmsTemplate and any JmsListenerContainerFactory created by DefaultJmsListenerContainerFactoryConfigurer. Our JSON converter needs the spring-boot-starter-json dependency.

JmsTemplate makes it simple to send messages to a JMS destination. In the main runner method, after starting things up, you can use jmsTemplate to send an Email POJO. Because our custom MessageConverter has been automatically associated to it, a JSON document is generated in a TextMessage only.

Two beans that you do not see defined are JmsTemplate and ConnectionFactory. These are created automatically by Spring Boot. Spring Boot also automatically discovers the @JmsListener-annotated methods when the JMS infrastructure is available, that is there is no need to add @EnableJms.

By default, Spring Boot tries to connect to an artemis broker running on the local machine. It is also possible to embed the broker by adding the following configuration property:

spring.artemis.mode=embedded

You also need to add a dependency to org.apache.activemq:artemis-jakarta-server.

By default, Spring Boot creates a JmsTemplate configured to transmit to queues by having pubSubDomain set to false. The JmsMessageListenerContainer is also configured the same way. To override, set spring.jms.pub-sub-domain=true through Spring Boot’s property settings (either inside application.properties or by setting an environment variable). Then make sure the receiving container has the same setting.

Note
Spring’s JmsTemplate can receive messages directly through its receive method, but that works only synchronously, meaning that it blocks. That is why we recommend that you use a listener container such as DefaultMessageListenerContainer with a cache-based connection factory, so you can consume messages asynchronously and with maximum connection efficiency.

When it runs, buried amidst all the logging, you should see these messages:

Sending an email message.
Received <Email{[email protected], body=Hello}>

Summary

Congratulations! You have developed a publisher and consumer of JMS-based messages.

gs-messaging-jms's People

Contributors

alek-sys avatar bclozel avatar btalbott avatar cbeams avatar fisco-unimatic avatar fml2 avatar gregturn avatar habuma avatar jochen777 avatar joshlong avatar robertmcnees avatar royclarkson avatar sergiovlvitorino avatar snicoll avatar spring-operator avatar wilkinsona avatar zyro23 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gs-messaging-jms's Issues

PubSubDomain

I don't know why, but on my computer the code works only when container.setPubSubDomain; is set to false and not true like the code.
It's a bug ?

The code fails with Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jms.support.converter.MessageConverter]: Factory method 'jascksonJmsMessageConverter' threw exception with message: com/fasterxml/jackson/databind/ObjectMapper

Perhaps it needs to include jackson databind in the maven

com.fasterxml.jackson.core jackson-databind 2.14.1

After including this library the error changes to
jakarta.jms.JMSException: Failed to create session factory

Perhaps it needs a JMS broker running. However the guide does not provide any instructions. It would be better if it could provide steps like it was provided for messaging with RabbitMq and Redis

Dependencies should be listed clearly.

I built the project by the Spring Initializer on VS Code and I had to check this github repo code for the differences because after all the steps I followed the app had not worked. I believe the dependecies artemis-jakarta-server and spring-boot-starter-json should be clearly stated in the tutorial.

Upgrade to latest Spring Boot version

An easy place to get started with contributing to Spring is keeping the Spring Boot version up-to-date, so I'm adding this issue as an invitation to first-time contributors.

You need to set the Spring Boot version in:

  • initial/build.gradle
  • initial/pom.xml
  • complete/build.gradle
  • complete/pom.xml

Then run test/run.sh to validate the upgrade worked as expected.

Please clarify DefaultMessageListenerContainer and CachingConnectionFactory relation

Readme says:

That’s why we recommend that you use a listener container such as DefaultMessageListenerContainer with a cache-based connection factory

This statement is fulfilled by AbstractJmsListenerContainerFactory#createListenerContainer - on debug I see CachingConnectionFactory is passed in line 190.

On the other hand, javadoc https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jms/listener/DefaultMessageListenerContainer.html says:

Note: Don't use Spring's CachingConnectionFactory in combination with dynamic scaling. Ideally, don't use it with a message listener container at all, since it is generally preferable to let the listener container itself handle appropriate caching within its lifecycle. Also, stopping and restarting a listener container will only work with an independent, locally cached Connection - not with an externally cached one.

I'm confused: Should CachingConnectionFactory be used or not?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.