Is it possible to get messages from an IBM MQ (synchronously or asynchronously) using Spring JMS alone - without using any Bean?
I am looking for a design where I can get messages from an MQ (IBM in this case) using Spring alone - process the message and pass it on.
Kindly suggest if it is possible. Thank you.
You can just use a JmsTemplate (synchronous) or DefaultMessageListenerContainer (asynchronous) directly, without declaring them as beans; be sure to call afterPropertiesSet() after setting the properties and before start() ing the container, though.
Related
I am trying to configure concurrent consumers in spring to consume messages from RabbitMQ, in order to achieve that i have configured consumers in two ways
1.annotated a method with #RabbitListener(queues = "name of queue")
2.implementing "MessageListener" interface and overriding onMessage(Message message)
In my case both the ways worked fine, but i am unable to figure out what is the advantage/disadvantage of using #RabbitListener() for starting a consumer over the other way.
Also adding to that i have configured "DirectMessageListenerContainer" in my configuration and mapped it to "MessageListener" implementation to achieve concurrent consumers, my question here is can we do the same mapping for consumer implemented through #RabbitListener() and if so how. I couldnt find any source on how a consumer started with a #RabbitListener() annotated method can be configured with a "DirectMessageListenerContainer"
Any Help is appreciated.
#RabbitListener is simply a higher-level abstraction. It uses the listener container underneath.
When using spring boot, use the ...listener.type application property to specify which type of container you want.
The default is simple.
What are we doing?
We are using mq-jms-spring-boot-starter and #JMSListener-annotation to implement an Message-Listener for a IBM MQ queue (lets call this: QueueA).
When an exception is thrown within the function annotated with #JMSListener the current message is automatically re-queued in the connected QueueA. At the MQ-Server we configured a retry-count (3 retries) and after 3 un-successful retries the message is send to a backout-queue (QueueA-BACKOUT).
What's our question?
Basically we want to use the automatic mechanism provided by #JMSListener to re-queue a message but with a delay before doing so.
For testing purposes we use ActiveMQ. There we could easily configure an initialRedeliveryDelay/redeliveryDelay in the ConnectionFactory.
What is the equivalent way to configure something like this for IBM MQ (using the mentioned Spring Starter)?
(INFO: we did not implement an errorhandler for the listener yet, might this be the right place to do something like this? Or is there a simple configuration-style option to solve this?)
I want a Java class (jms receiver) which always run in background and check for any message arrive in jms queue.How it can be possible? Please help.
What you want is a JMS MessageListener. Create your JMS client resources (e.g. connection/context, session, etc.) like normal and then invoke setMessageListener on your consumer passing in your implementation of the MessageListener interface. This is pretty basic JMS stuff so you can find more detailed tutorials online.
Can someone explain different ways of configuring message listener.
I know two ways:
Spring Jms Listener
EJB MDB way.
Are there any other ways (should be applicable to both IBM MQ and Active MQ)?
For the first question, your proposed ways are good ones with Camel JMS.
For the second question take a look at Java JMS mix messaging implementations
if you want to use the same client without changing anything you have to use AMQP ptotocol wich is designed for this.
here is 2 examples :
ActiveMQ AMQP with JMS transformer leveraging spring Integration
Unable to access ActiveMQ using JMS based code and amqp 1.0
I have a Spring Integration application, where I have a JMS inbound channel adapter that will receive messages from a queue in a remote JMS broker. I'm looking up the connection factory directly from the broker's remote JNDI service and this is what I use to set up my inbound channel adapter. I understand that behind the scenes there is a DefaultMessageListenerContainer. According to AbstractMessageListenerContainer javadocs, found here, if "sessionTransacted" is set to "true" for the DMLC, local JMS transactions will be used for the delivery of messages from the broker.
I'm not interested in having the receipt of messages to be part of externally managed transactions.
Now, if the JMS broker provides a resource adapter and therefore there is a JCA managed connection factory (that might be capable of participating in JTA transactions) configured in a JBoss App server where my Spring Integration is running packaged in a war . I could use this instead of directly looking up from the broker's JNDI as I described above. Since I am not interested in global transactions, I don't see the value of using this JCA connection factory, moreover I don't know if the caching of connections/sessions that JCA does might clash with the DMLC caching strategy. Additionally I'm not sure if adding a JCA layer to wrap the original connection factory will impact performance.
Which is the right approach then, take connection factory directly from broker JNDI and let DMLC handle everything or take a JCA managed connection? There seems to be a not very well documented school of thought that tells that JCA is safer and more robust, but if I'm not using EJBs I dont see how this can be true.