TypeMismatchNamingException in spring boot with IBM MQ - spring-boot

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.

Related

Can't deploy Spring Boot (v2.6.6) project to Weblogic (v12.2.1.3) , due to javax.naming.NameNotFoundException

I'm trying to deploy a Spring boot application to weblogic, and connect the app to a Gridlink datasource using this method in #configuration to get the data source.
#Bean(name = "dataSourceA",destroyMethod = "")
public DataSource dataSourceA() throws NamingException {
JndiTemplate jndiTemplate = new JndiTemplate();
InitialContext ctx = (InitialContext) jndiTemplate.getContext();
return (DataSource) ctx.lookup(env.getProperty("DatabaseAGridLink"));
}
On Weblogic, the JNDI name for the data source is "DatabaseAGridLink", which I am hardcoding in the creation of the bean.
However, when I compile my project into a .war file and host on Weblogic- it runs into an error when searching for the data source:
javax.naming.NameNotFoundException: Unable to resolve 'DatabaseAGridLink'. Resolved ''; remaining
name 'DatabaseAGridLink'
If I restart my Weblogic, it no longer errors and the Spring Boot application can connect to the datasource on Weblogic, run db queries- functioning without issues. Problem is, this isn't a real solution- as any time the project is updated the Weblogic needs to be restarted and there are other applications running which makes this impossible irrespective of being a bad solution in the first place.
Thinking it's an issue with how the datasource is initialized in Spring boot, I have tried other methods of connection such as:
#Bean
public DataSource dataSourceA() throws Exception{
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("DatabaseAGridLink");
}
Or different ways of specifying the JNDI name on both data source initialization beans:
ctx.lookup(env.getProperty("java:jdbc/DatabaseAGridLink"));
ctx.lookup(env.getProperty("jdbc/DatabaseAGridLink"));
ctx.lookup(env.getProperty("java:comp/jdbc/DatabaseAGridLink"));
dataSourceLookup.getDataSource("java:jdbc/DatabaseAGridLink");
etc..
These changes has had no effect, other than the name no longer being found as none of these other naming schemes are valid.
What could be causing this failure of datasource connection between Spring Boot and a Weblogic instance? (Especially considering that it succeeds after weblogic is restarted, which seems to imply that the Spring boot app is indeed looking for the correct JNDI name with it's bean and this isn't a naming problem)

Send message to a JMS queue using Spring Boot

I am new to Spring JMS. My application is developed using Spring Boot and is deployed in JBoss EAP 7.2.0. I have a remote queue which is an Active MQ Artemis queue which is also embedded within JBoss EAP 7.2.0. Can anyone please suggest me how to send a message to the remote JMS queue using JmsTemplate of Spring Boot? Basically I am not getting how should I define the remote connectionFactory to connect to the remote queue.
Add the following to application properties as your application is deployed in application server
spring.jms.jndi-name=java:/<your connection factory name for artemis>
Add artemis dependency and let spring boot autoconfigure jmsTemplate
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
Autowire jmsTemplate and send message
#Component
public class MyMessageSender {
#Autowired
JmsTemplate jmsTemplate;
public void send(String msg){
jmsTemplate.convertAndSend("my.queue.name", msg);
}
}
Optionally you can configure message converters and send pojos as message and let spring take care of converting it to json. For example
#Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}

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

Spring Batch combined with Atomikos not working

I’m having trouble configuring an Tomcat – Spring Batch – Atomikos combination.
I have configured the following (I’m not mentioning the JMS configuration)
Atomikos DataSource (proxy) based on
com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory for Oracle XA datasource.
JtaTransactionManager based on
transactionManager based on com.atomikos.icatch.jta.J2eeTransactionManager
userTransaction based on
com.atomikos.icatch.jta.J2eeUserTransaction
When executing a batch job I receive the following error:
Caused by: java.lang.RuntimeException: Transaction Service Not Running?
at com.atomikos.icatch.jta.J2eeUserTransaction.checkSetup(J2eeUserTransaction.java:70)
at com.atomikos.icatch.jta.J2eeUserTransaction.getStatus(J2eeUserTransaction.java:125)
at org.springframework.transaction.jta.JtaTransactionManager.
isExistingTransaction(JtaTransactionManager.java:797)
Debugging revealed the following:
Spring Batch makes use of TaskletStep. This class uses a PlatformTransactionManager that is instantiated with a DataSourceTransactionManager? The datasource is referring to a AtomikosDataSourceBean, that seems ok.
I have several questions:
Where is this DataSourceTransactionManager coming from? I have defined a JtaTransactionManager!
I thought the AtomikosDataSourceBean acts like a proxy to connect to JtaTransactionManager. Why is Atomikos given the error “Transaction Service Not Running?”
Spring Batch: 2.1.8
Atomikos: 3.9.3

Resources