I am trying to load queue connection factory configurations using JNDI into My application which works fine when we use Queue Manager(IBM Websphere MQ) which is not secured. But when we changed to secured Queue Manager the same JNDI look up does not work. I am adding the logic used for JNDI look up below.
public class EpsJmsConfig {
#Bean
public JndiObjectFactoryBean connectionFactoryBean() {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("jms/NotificationCF");
bean.setResourceRef(false);
return bean;
}
#Bean
public ConnectionFactory connectionFactory() {
return (ConnectionFactory) connectionFactoryBean().getObject();
}
#Bean
public JndiObjectFactoryBean epsXiBillPayNotificationDestinationBean() {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("jms/epsXiBillPayNotificationQ");
return bean;
}
#Bean
public Destination epsXiBillPayNotificationDestination() {
return (Destination) epsXiBillPayNotificationDestinationBean().getObject();
}
#Bean(name = "xiBillpayNotificationJmsTemplate")
public JmsTemplate xiBillpayNotificationJmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory());
jmsTemplate.setDefaultDestination(epsXiBillPayNotificationDestination());
return jmsTemplate;
}
}
Related
I should be able to configure multiple JmsListenerContainerFactory beans from multiple JMS JNDI names configured in the server and I should be able to do the following.
#EnableJms
#Configuration
public class JmsConfig
{
#Bean
public JmsListenerContainerFactory<?> containerFactoryONE(#Qualifier("from-JNDI-ONE") ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer)
{
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
#Bean
public JmsListenerContainerFactory<?> containerFactoryTWO(#Qualifier("from-JNDI-TWO") ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer)
{
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
}
and should be able to listen to the message from two different servers as below
#Component
public class JMSListener
{
#JmsListener(destination = "jms/ActiveMQ-Server-ONE", containerFactory="containerFactoryONE")
public void receiveMessageFromJMSServerONE(String message)
{
System.out.println(message);
}
#JmsListener(destination = "jms/ActiveMQ-Server-TWO", containerFactory="containerFactoryTWO")
public void receiveMessageFromJMSServerTWO(String message)
{
System.out.println(message);
}
}
Hey guys I have an application with spring boot that receives a message from a TIBCO EMS, I perform some operations and finally, I need to send that message to an MQ
I have a class Consumer
In the line #JmsLister I have a destination queue from TIBCO EMS because is who sends the message and when I called a method sendMessage I pass a destination queue from the parameter that is to MQ
#Component
public class ClassConsumer {
#JmsListener(destination = "${jms.destination.queue}",
containerFactory = Constants.GENERIC_JMS_EMS_LISTENER_BEAN_NAME)
public void consumerProcess(String request, #Header(JmsHeaders.ID) String id) {
ValoresDtoIn in = operationService.convertXml(request);
DatosDto datosDto = operationService.fillObject(in);
this.operacionService.sendMessage(datosDto, mqConstants.getMqDestiQueue(),id);
}
}
and when it reaches the sendMessage method it marks the error
This is my class service
#Service
public class Operations implements OperationsService {
#Autowired
#Qualifier(Constants.GENERIC_JMS_TEMPLATE_BEAN_NAME)
private JmsTemplate jmsTemplate;
#Override
public void sendMessage(String message, String destination, String id) {
ConnectionFactory connectionFactory = this.jmsTemplate.getConnectionFactory();
if (!Objects.isNull(connectionFactory)) {
try (Connection connection = connectionFactory.createConnection()) {
Queue queue = connection.createSession().createQueue(destination);
this.processorService.setId(id);
this.jmsTemplate.convertAndSend(queue, message, this.processorService);
} catch (JMSException ex) {
LOGGER.error(ex.getMessage(), ex);
}
}
}
}
and I had two classes from configuration, one for TibEms and the other from MQ
to TIBCO
#Configuration
public class TibConnectionConfig {
#Bean(name = Constants.GENERIC_CONNECTION_FACTORY_BEAN_NAME)
public TibjmsConnectionFactory tibjmsConnectionFactory() throws JMSException {
TibjmsConnectionFactory tibjmsConnectionFactory = new TibjmsConnectionFactory();
tibjmsConnectionFactory.setServerUrl(constants.getGenericHost());
tibjmsConnectionFactory.setUserName(constants.getGenericUsername());
tibjmsConnectionFactory.setUserPassword(constants.getGenericPassword());
tibjmsConnectionFactory.setReconnAttemptTimeout(constants.getGenericReconnAttemptTimeout());
tibjmsConnectionFactory.setSSLPassword(constants.getCertificatePassword());
tibjmsConnectionFactory.setSSLTrustedCertificate(constants.getCertificatePath());
tibjmsConnectionFactory.setSSLEnableVerifyHostName(false);
return tibjmsConnectionFactory;
}
#Bean(name = Constants.GENERIC_CACHING_CONNECTION_FACTORY_BEAN_NAME)
public CachingConnectionFactory cachingConnectionFactory(
#Qualifier(Constants.GENERIC_CONNECTION_FACTORY_BEAN_NAME) TibjmsConnectionFactory tibjmsConnectionFactory)
throws JMSException {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(tibjmsConnectionFactory());
cachingConnectionFactory.setSessionCacheSize(constants.getGenericCacheSize());
return cachingConnectionFactory;
}
#Bean(name = Constants.GENERIC_JMS_TEMPLATE_BEAN_NAME)
public JmsTemplate jmsTemplate(
#Qualifier(Constants.GENERIC_CACHING_CONNECTION_FACTORY_BEAN_NAME) CachingConnectionFactory connection)
throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate(connection);
jmsTemplate.setDefaultDestinationName(constants.getGenericDestinationQueue());
jmsTemplate.setReceiveTimeout(constants.getGenericReceiveTimeout());
jmsTemplate.setDeliveryMode(constants.getGenericDeliverymode());
jmsTemplate.setSessionAcknowledgeModeName(constants.getSessionMode());
jmsTemplate.setExplicitQosEnabled(true);
jmsTemplate.setSessionTransacted(false);
return jmsTemplate;
}
#Bean(name = Constants.GENERIC_JMS_EMS_LISTENER_BEAN_NAME)
public DefaultJmsListenerContainerFactory jmsEmsListenerContainerFactory(
#Qualifier(Constants.GENERIC_CACHING_CONNECTION_FACTORY_BEAN_NAME) CachingConnectionFactory connection,
GenericErrorHandler genericErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connection);
factory.setErrorHandler(genericErrorHandler);
factory.setConcurrency(Constants.CONCURRENT_CONSTANT);
return factory;
}
}
To MQ
#Configuration
public class MqConnectionConfig {
#Bean(name = Constants.CONNECTION_FACTORY_BEAN_NAME)
public MQConnectionFactory mqConnectionFactory() throws JMSException {
MQConnectionFactory mqConnectionFactory = new MQConnectionFactory();
mqConnectionFactory.setHostName(constants.getHost());
mqConnectionFactory.setPort(constants.getPort());
mqConnectionFactory.setQueueManager(constants.getManager());
mqConnectionFactory.setChannel(constants.getChannel());
mqConnectionFactory.setTransportType(constants.getTranspType());
return mqConnectionFactory;
}
#Bean(name = Constants.CACHING_CONNECTION_FACTORY_BEAN_NAME)
public CachingConnectionFactory cachingConnectionFactory(
#Qualifier(Constants.CONNECTION_FACTORY_BEAN_NAME) MQConnectionFactory mqConnectionFactory)
throws JMSException {
CachingConnectionFactory cachingConnectionFactory =
new CachingConnectionFactory(mqConnectionFactory());
cachingConnectionFactory.setSessionCacheSize(10);
return cachingConnectionFactory;
}
#Bean(name = Constants.TEMPLATE_BEAN_NAME)
public JmsTemplate jmsTemplate(
#Qualifier(Constants.CONNECTION_FACTORY_BEAN_NAME) CachingConnectionFactory cachingConnectionFactory)
throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
jmsTemplate.setDefaultDestinationName(constants.getMqDestiQueue);
jmsTemplate.setReceiveTimeout(constants.getTimeout());
jmsTemplate.setDeliveryMode(constants.getDeliveryMode());
jmsTemplate.setSessionAcknowledgeModeName(constants.getSessionMode());
jmsTemplate.setExplicitQosEnabled(true);
jmsTemplate.setSessionTransacted(false);
return jmsTemplate;
}
#Bean(name = Constants.EMS_LISTENER_BEAN_NAME)
public DefaultJmsListenerContainerFactory mqJmsListenerContainerFactory(
#Qualifier(Constants.CACHING_CONNECTION_FACTORY_BEAN_NAME) CachingConnectionFactory cachingConnectionFactory,
GenericEmsErrorHandler genericIbmErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(cachingConnectionFactory);
factory.setErrorHandler(genericIbmErrorHandler);
factory.setConcurrency(Constants.CONCURRENT_CONSTANT);
return factory;
}
}
and when I running the app sends me this error
ErrorHandler, unmanaged exception description: Listener method Consumer.consumerProcess(java.lang.String,java.lang.String)'
threw exception; nested exception is org.springframework.jms.InvalidDestinationException: Not allowed to create destination;
nested exception is javax.jms.InvalidDestinationException: Not allowed to create destination.
Can anyone help me? What is wrong?
I have no idea how to fix the error
I have configured an ActiveMQ message queue with transactions in a Spring Boot application.
Here is my beans configuration:
#Bean
public DefaultJmsListenerContainerFactory jmsListenerFactory(DefaultJmsListenerContainerFactoryConfigurer configurer,
#Qualifier("jmsTransactionManager") PlatformTransactionManager transactionManager,
JmsErrorHandler errorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory());
factory.setMessageConverter(messageConverter());
factory.setTransactionManager(transactionManager);
factory.setSessionTransacted(true);
factory.setErrorHandler(errorHandler);
return factory;
}
#Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(20000);
redeliveryPolicy.setRedeliveryDelay(20000);
redeliveryPolicy.setMaximumRedeliveryDelay(20000);
redeliveryPolicy.setBackOffMultiplier(2);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(-1);
redeliveryPolicy.setDestination(defaultDestination());
return redeliveryPolicy;
}
#Bean
public ActiveMQConnectionFactory connectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(getAddress());
connectionFactory.setRedeliveryPolicy(redeliveryPolicy());
return connectionFactory;
}
#Bean(initMethod = "start", destroyMethod = "stop")
public BrokerService broker() throws Exception {
final BrokerService broker = new BrokerService();
broker.addConnector(getAddress());
PersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
persistenceAdapter.setDirectory(new File(...));
broker.setPersistenceAdapter(persistenceAdapter);
broker.setBrokerName(getName());
broker.setPersistent(true);
broker.setDataDirectoryFile(new File(...));
broker.setSchedulerSupport(true);
broker.setUseJmx(true);
return broker;
}
#Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory());
jmsTemplate.setMessageConverter(messageConverter());
jmsTemplate.setSessionTransacted(true);
jmsTemplate.setSessionAcknowledgeMode(Session.SESSION_TRANSACTED);
jmsTemplate.setDefaultDestination(defaultDestination());
jmsTemplate.setPubSubDomain(false);
return jmsTemplate;
}
Although maximum redeliveries attribute is working as expected (unlimited) the delay setting is not, which is strange.
Any tips on what might be the issue?
EDIT
I found that the issue disappears when I comment out this:
factory.setTransactionManager(transactionManager);
from jmsListenerFactory. I am not sure if I understand the reason though and if it is safe to completely remove it.
I have a spring application deplyoed in WebSphere container and I need to configure JMS but I have a problem. Sending messages works fine but MessageListener doesn't consumes messages.
This is my jms config:
#Bean
public PlatformTransactionManager transactionManager() {
return new WebSphereUowTransactionManager();
}
#Bean
public ConnectionFactory jmsConnectionFactory() throws NamingException {
return jndi().lookup(CONNECTION_FACTORY_ADDRESS, ConnectionFactory.class);
}
#Bean(name = "queue")
public Queue jmsQueue() throws NamingException {
return jndi().lookup(QUEUE_ADDRESS, Queue.class);
}
#Bean(name = "replyQueue")
public Queue jmsReplyQueue() throws NamingException {
return jndi().lookup(REPLY_QUEUE_ADDRESS, Queue.class);
}
#Bean
public DestinationResolver jmsDestinationResolver() {
return new JndiDestinationResolver();
}
#Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() throws NamingException {
final DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(jmsConnectionFactory());
factory.setDestinationResolver(jmsDestinationResolver());
factory.setTransactionManager(transactionManager());
factory.setSessionTransacted(true);
factory.setConcurrency("3-10");
factory.setTaskExecutor(threadPoolTaskExecutor());
return factory;
}
#Bean
public TaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setKeepAliveSeconds(20);
return executor;
}
I get this exception on startup:
[08.06.17 18:23:38:765 MSK] 00000409 DefaultMessag W org.springframework.jms.listener.DefaultMessageListenerContainer handleListenerSetupFailure Setup of JMS message listener invoker failed for destination 'jms/test_queue' - trying to recover. Cause: No JTA UserTransaction available - programmatic PlatformTransactionManager.getTransaction usage not supported
I read that It can be cause of the conflict with hibernate transitive dependency. I've tried to exclude jboss-transaction-api_1.1_spec dependency from hibernate-core but it didn't help.
I've also tried to use WorkManagerTaskExecutor:
#Bean
public TaskExecutor taskExecutor() {
WorkManagerTaskExecutor executor = new WorkManagerTaskExecutor();
executor.setWorkManagerName("wm/default");
return executor;
}
But exception is still throws.
What could be the problem?
I am working on a JMS Queue for a requirement on JBOSS AS 7.
I am banging my head against the wall :(
I end up getting this error for the queue. It works fine when all of this configuration is part of the applicationContext.xml. We are avoiding cml config and moving to java config. That is when the issue comes up. Please help!!!
Here is the Queue Config in standalone.xml:
<jms-queue name="ticketOrderQueue">
<entry name="queue/ticketOrderQueue"/>
</jms-queue>
Here is my java spring config class.
//JMS Configuration
#Bean
public ConnectionFactory jmsConnectionFactory() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("java:/ConnectionFactory");
jndiObjectFactoryBean.afterPropertiesSet(); //HERE
return (ConnectionFactory) jndiObjectFactoryBean.getObject();
}
#Bean
public Queue requestsQueue() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("queue/ticketOrderQueue");
jndiObjectFactoryBean.setProxyInterface(Queue.class);
jndiObjectFactoryBean.afterPropertiesSet();
logger.debug("The Quues is :" + jndiObjectFactoryBean.getObject());
return (Queue) jndiObjectFactoryBean.getObject();
}
#Bean
public JmsTemplate jmsTemplate() throws IllegalArgumentException, NamingException {
final JmsTemplate jmsTemplate = new JmsTemplate(jmsConnectionFactory());
jmsTemplate.setDefaultDestination(requestsQueue());
return jmsTemplate;
}
#Bean
public CustomerDetailedReportJMSListener queueMessageReceiver() {
return new CustomerDetailedReportJMSListener();
}
#Bean
public DefaultMessageListenerContainer jmsListenerContainer() throws IllegalArgumentException, NamingException {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setConnectionFactory(jmsConnectionFactory());
dmlc.setDestination(requestsQueue());
MessageListenerAdapter listener = new MessageListenerAdapter();
listener.setDelegate(queueMessageReceiver());
listener.setDefaultListenerMethod("onMessage");
dmlc.setMessageListener(listener);
dmlc.setConcurrentConsumers(10);
dmlc.afterPropertiesSet();
dmlc.start();
return dmlc;
Well, after a lot of trial and errors, it turned out that my classpath was overloaded with the jms jars. Once I got rid of the extra ones, I no more got the error.