Atomikos Forum |
|
Hi all I have following exception:
2011-03-18 18:40:47,396 WARN com.atomikos.diagnostics.Slf4jConsole - atomikos connection pool 'XAactiveMQ': error while trying to recycle java.lang.NullPointerException at com.atomikos.datasource.xa.session.SessionHandleState.isActiveInTransaction(SessionHandleState.java:286) at com.atomikos.jms.AtomikosJmsXaSessionProxy.isInTransaction(AtomikosJmsXaSessionProxy.java:230) at com.atomikos.jms.AtomikosJmsConnectionProxy.isInTransaction(AtomikosJmsConnectionProxy.java:354) at com.atomikos.jms.AtomikosPooledJmsConnection.canBeRecycledForCallingThread(AtomikosPooledJmsConnection.java:160) at com.atomikos.datasource.pool.ConnectionPool.recycleConnectionIfPossible(ConnectionPool.java:103) at com.atomikos.datasource.pool.ConnectionPool.borrowConnection(ConnectionPool.java:133) at com.atomikos.jms.AtomikosConnectionFactoryBean.createConnection(AtomikosConnectionFactoryBean.java:585) at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.access$0(AbstractPollingMessageListenerContainer.java:1) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer$MessageListenerContainerResourceFactory.createConnection(AbstractPollingMessageListenerContainer.java:525) at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:297) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:288) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947) at java.lang.Thread.run(Thread.java:662) I checked code for: public boolean isActiveInTransaction ( CompositeTransaction tx ) { boolean ret = false; if ( currentContext != null && tx != null ) ret = currentContext.isInTransaction ( tx ); return ret; } I think in this case currentContext is null but you have check before currentContext.isInTransaction ( tx ) invocation, seems from another thread currentContext was modified
No I am using Spring container with DefaultMessageListenerContainer and I all my buss. logic is in MessageListener. I am not managing any JMS connection, session and etc everything done by Spring and Atomikos:
Here is versions of libraries: Atomikos TransactionsEssentials ® 3.7.0 Spring 3.0.5 Configs: <!-- Construct Atomikos UserTransactionManager, needed to configure Spring --> <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <!-- when close is called, should we force transactions to terminate or not? --> <property name="forceShutdown" value="true"/> </bean> <!-- Also use Atomikos UserTransactionImp, needed to configure Spring --> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300"/> </bean> <!-- Configure the Spring framework to use JTA transactions from Atomikos --> <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager"/> <property name="userTransaction" ref="atomikosUserTransaction"/> </bean> <bean id="xaFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory"> <property name="brokerURL" value="ssl://sargis:61617?jms.watchTopicAdvisories=false"/> <property name="userName" value=""/> <property name="password" value=""/> <property name="redeliveryPolicy" ref="redeliveryPolicy"/> </bean> <bean id="atomikosConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init"> <property name="uniqueResourceName" value="XAactiveMQ"/> <property name="xaConnectionFactory" ref="xaFactory"/> <property name="minPoolSize" value="10"/> <property name="maxPoolSize" value="40"/> <property name="maxIdleTime" value="120"/> </bean> <bean id="jmsListenerManager" class="com.webbfontaine.twm.accounting.epaylog.emess.jms.JMSListenerManager"> <property name="concurrency" value="2-4"/> <property name="jmsListeners"> <list> <bean class="com.webbfontaine.twm.accounting.epaylog.emess.jms.JMSMessageListener"> <property name="vaspId" value="xxx"/> <property name="bankInboxQueueName" value="xxx"/> <property name="bankOutboxQueueName" value="xxx"/> </bean> </list> </property> </bean> and public class JMSListenerManager implements ApplicationContextAware { private static final String DMLC = "DMLC"; private List<JMSMessageListener> jmsListeners; private GenericApplicationContext applicationContext; private String concurrency; public void setJmsListeners(List<JMSMessageListener> jmsListeners) { this.jmsListeners = jmsListeners; } public void start() { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory(); for (final JMSMessageListener listener : jmsListeners) { String beanName = String.format("%s%s", listener.getVaspId(), DMLC); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DefaultMessageListenerContainer.class) .addPropertyReference("transactionManager", "jtaTransactionManager") .addPropertyReference("connectionFactory", "atomikosConnectionFactory") .addPropertyValue("concurrency", concurrency) .addPropertyValue("sessionTransacted", Boolean.TRUE) .addPropertyValue("destinationName", listener.getBankOutboxQueueName()) .addPropertyValue("messageListener", listener); beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition()); DefaultMessageListenerContainer bean = applicationContext.getBean(beanName, DefaultMessageListenerContainer.class); bean.start(); } } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = (GenericApplicationContext) applicationContext; } public void setConcurrency(String concurrency) { this.concurrency = concurrency; } }
And one question as I understand its safe to share com.atomikos.jms.AtomikosConnectionFactoryBean between different DefaultMessageListenerContainer, is it correct?
Just one correction:
<list> <bean class="com.webbfontaine.twm.accounting.epaylog.emess.jms.JMSMessageListener"> <property name="vaspId" value="xxx"/> <property name="bankInboxQueueName" value="xxx"/> <property name="bankOutboxQueueName" value="xxx"/> </bean> <bean class="com.webbfontaine.twm.accounting.epaylog.emess.jms.JMSMessageListener"> <property name="vaspId" value="yyy"/> <property name="bankInboxQueueName" value="yyy"/> <property name="bankOutboxQueueName" value="yyy"/> </bean> </list> I have 2 registered MessageListener
Hi,
Try to use com.atomikos.jms.extra.MessageDrivenContainer instead of Spring's. Also, try setting forceShutdown=false in your config. Lastly, make sure to respect proper init and shutdown of your beans like here: http://www.atomikos.com/Documentation/SpringIntegration#Optimizing_the_Init_and_Close_Or HTH
Make the transaction manager depends on all your JDBC and JMS connection factories: this ensures that connections are kept until AFTER the transaction manager has terminated all transactions during shutdown.
I have: <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="xaDataSource, atomikosXAConnectionFactory"> <!-- when close is called, should we force transactions to terminate or not? --> <property name="forceShutdown" value="false"/> </bean> <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager"/> <property name="userTransaction" ref="atomikosUserTransaction"/> </bean> Can you clarify please I should I dependency to jtaTransactionManager or atomikosTransactionManager |