Spring - When a Destination JndiObjectFactoryBean is cached, does it keep any connection open to the JMS broker? - spring

We configure our JMS destinations via JNDI lookup as follows:
#Bean
JndiObjectFactoryBean myTopic(#Value("${topic}") String topic,
JndiTemplate jndiTemplate) {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiTemplate(jndiTemplate);
jndiObjectFactoryBean.setJndiName(topic);
return jndiObjectFactoryBean;
}
On initialisation of this bean, Spring confirms the object exists and caches it for use later. Does the caching of this Destination involve a persistent connection being created to our broker as well? Or is the connection only physically created when our CachingConnectionFactory is instantiated?

The (only and shared) connection is created when you call createConnection() for the 1st time on your CachingConnectionFactory instance and released on the call to destroy() or resetConnection() as stated per the contract (CachingConnectionFactory inherit from SingleConnectionFactory) :
A JMS ConnectionFactory adapter that returns the same Connection from all createConnection() calls, and ignores calls to Connection.close()

Related

TypeMismatchNamingException in spring boot with IBM MQ

I am trying to create a Spring boot project to read messages from a queue and do some processing.
I have defined the Jndi ConnectionFactory in application.properties
spring.jms.jndi-name=java:/MyConnectionFactory
On starting the application I am getting the following exception:
Caused by: org.springframework.jndi.TypeMismatchNamingException: Object of type [class com.ibm.mq.connector.outbound.ConnectionFactoryImpl] available at JNDI location [java:/MyConnectionFactory] is not assignable to [javax.jms.ConnectionFactory]
I am deploying the code on a jboss server with the given jndi.
Not sure if in this scenario some different implementation is needed for the ConnectionFactory.
#Bean public DefaultMessageListenerContainer orderMessageListenerContainer() {
DefaultMessageListenerContainer endpoint = new DefaultMessageListenerContainer();
endpoint.setMessageListener(new YourMessageListener());
endpoint.setDestination("yourDestination");
endpoint.setConnectionFactory(connectionFactory());
return orderDefaultJmsListenerContainerFactory().createListenerContainer(endpoint);
}
Solved manually with DefaultMessageListenerContainer.

how to add several activemq NetworkConnectors in spring boot with java config, not configued with XML file

usually, we add NetworkConnectors configuration in activemq.xml before we start the activemq service as below:
<networkConnectors>
<networkConnector uri="static:(tcp://localhost:62001)"/>
</networkConnectors>
but this time, i just used spring boot with activemq embeded. and i want to configure more networkConnectors danymiclly when the mq running. so i could not choose to add these in activemq.xml. but need to configure with java code in spring boot. i don't know how to implement this.
you define the broker bean and add what you want as you do in xml
#Bean
public BrokerService broker() throws Exception {
BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:5671");
broker.addNetworkConnector("static:(tcp://localhost:62001)");
return broker;
}

Spring boot activemq overriding the connection factory

I am new to Spring boot and i am trying to lookup my own connection factory instead of using the default 'ConnectionFactory' which Spring boot provides and also trying to lookup the already defined queue without using dynamicqueues.
How can i do that?
Should i add jndi.properties file and add it there so i can lookup?
Can someone suggest?
The Spring Integration configuration by default is looking for a
Spring Bean called ‘connectionFactory’.
Spring Boot by default,
creates the JMS connection factory using the name
‘jmsConnectionFactory’.
#Bean
public ConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
return connectionFactory;
}
https://github.com/spring-projects/spring-boot/blob/v1.5.9.RELEASE/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java

set heartbeat property on rabbitmq autoconfig connectionfactory bean

How should I set the heartbeat property on a CachingConnectionFactory bean in rabbitmq spring?
This is in a cloud foundry environment. So the application will be using a service binding via manifest file and I don't have the broker host name.
In my SimpleMessageListenerContainer bean, I make use of the CachingConnectionFactory bean and I guess it's autowired by Spring.
I could do in there,
#Bean
SimpleMessageListenerContainer container(CachingConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
connectionFactory.setRequestedHeartbeat(60);
container.setConnectionFactory(connectionFactory);
...
}
since I am not creating a bean for CachingconnectionFactory, I don't have a place for assigning that property, this is the only place I see for it.
Is there any other way to assign this property on ConnectionFactory in auto-configured setting?
thanks
See the Spring Boot Properties Documentation.
spring.rabbitmq.requested-heartbeat= # Requested heartbeat timeout, in seconds; zero for none.

Spring AMQP with two ConnectionFactory

I have an application with two ConnectionFactory (different brokers). They are configured with java classes:
       
       
#Bean
public ConnectionFactory ...
#Bean
public Queue ...
...
In rabbittemplate you can indicate the connection, but not in queues or in the exchanges, so they are being created in the two connections.
Do I have to use RabbitAdmin to create queues in only one of the two connections? is there any other way?
See the documentation : Conditional Declaration.
Starting with the 1.2 release, it is possible to conditionally declare these elements. This is particularly useful when an application connects to multiple brokers and needs to specify with which broker(s) a particular element should be declared.
You need a RabbitAdmin for each connection factory and use declared-by to indicate which admin(s) should declare each queue/exchange/binding.

Resources