ActiveMQ Data persistent Issue in Java Spring - java

I have an application which uses embedded activeMQ 5.11. At the start of the application it creates activemq-data\producerBroker\KahaDB folder at the class path location. I do want to change the location but spring.xml doesn't take a location.
Spring.xml as given,
<bean id="producerBroker" class="org.apache.activemq.broker.SslBrokerService">
<property name="brokerName" value="producerBroker" />
<property name="persistent" value="true" />
<property name="persistenceAdapter" ref="persistenceAdapter"/>
<property name="transportConnectors">
<list>
<bean class="org.apache.activemq.broker.TransportConnector">
<property name="name" value="xxx"></property>
<property name="uri" value="${transportConnectorURIs}"></property>
</bean>
</list>
</property>
<property name="jmsBridgeConnectors">
<list>
<bean class="org.apache.activemq.network.jms.JmsQueueConnector">
<property name="outboundQueueConnectionFactory">
<bean class="org.apache.activemq.ActiveMQSslConnectionFactory">
<property name="brokerURL" value="${brokerURL}" />
<property name="userName" value="${username}" />
<property name="password" value="${password}" />
<property name="trustStore" value="${trust.store.path}" />
<property name="trustStorePassword" value="${trust.store.password}" />
<!-- <property name="keyStore" value="${key.store.path}"/> -->
<!-- <property name="keyStorePassword" value="${key.store.password}"/> -->
</bean>
</property>
<property name="outboundQueueBridges">
<list>
<bean class="org.apache.activemq.network.jms.OutboundQueueBridge">
<constructor-arg value="${screenshotQueueName}" />
</bean>
<bean class="org.apache.activemq.network.jms.OutboundQueueBridge">
<constructor-arg value="${resultXmlQueueName}" />
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
<bean id="persistenceAdapter" class="org.apache.activemq.store.kahadaptor.KahaPersistenceAdapter">
<property name="directory" value="E:\test"/>
Current issue is it throws an error as "exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.apache.activemq.store.kahadaptor.KahaPersistenceA
apter] for bean with name 'kahaPersistenceAdapter' defined in class path resource [spring/resultupload/resultupload.xml]; nested exception is java.la
g.ClassNotFoundException: org.apache.activemq.store.kahadaptor.KahaPersistenceAdapter"
Anyone has experience in the directory change in activeMQ 5.11 in java spring?

The destination of the persistence location must be defined at the broker level.
The kahaPersistenceAdapter (which was file based) was removed with version 5.9. You should use the kahaDB.
kahaDB - uses KahaDB an embedded lightweight non-relational database
<broker brokerName="broker" persistent="true" useShutdownHook="false">
<transportConnectors>
<transportConnector uri="tcp://localhost:61616"/>
</transportConnectors>
<persistenceAdapter>
<kahaDB directory="e:/temp" ... />
</persistenceAdapter>
</broker>
all valid attributes: http://activemq.apache.org/schema/core/activemq-core-5.11.0-schema.html#kahaDB

Related

Spring Integration Atomikos transaction issue

I'm trying to integrate Atomikos transaction manager into a Spring Integration program that forwards JMS from ActiveMQ to a WebMethods ESB.
The spring integration part only retrieves JMs from local ActiveMQ broker and sends them to a distant ESB broker.
When I test the nominal case, JMS is sent well and passes through the ESB and is dispatched to the subscribers then.
When I test the case where ESB sending fails, I have an issue : the JMS is never published back. I suppose it's a transaction issue because the transaction should have been rolled back when program tried to publish on ESB broker but it seems not.
Here's my spring config :
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<!-- Atomikos Transaction Manager Defintion (JTA) -->
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close" depends-on="atomikosConnectionFactorySource,connectionFactoryDestination">
<property name="transactionTimeout" value="300" />
<property name="forceShutdown" value="false" />
</bean>
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="jmsXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="${source.java.naming.provider.url}" />
<property name="userName" value="${source.username}" />
<property name="password" value="${source.passwd}" />
</bean>
<bean id="atomikosConnectionFactorySource" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
init-method="init" destroy-method="close">
<property name="poolSize" value="1" />
<property name="uniqueResourceName" value="activemq" />
<property name="xaConnectionFactory" ref="jmsXaConnectionFactory" />
</bean>
<bean id="connectionFactorySource"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="jmsXaConnectionFactory" />
<property name="clientId" value="CustomerOrderForwarderID" />
<property name="reconnectOnException" value="true" />
</bean>
<!-- Destination JNDI Context -->
<bean id="jndiTemplateDestination" class="org.springframework.jndi.JndiTemplate"
lazy-init="true">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${destination.java.naming.factory.initial}</prop>
<prop key="java.naming.provider.url">${destination.java.naming.provider.url}</prop>
<prop key="java.naming.factory.url.pkgs">${destination.java.naming.factory.url.pkgs}</prop>
</props>
</property>
</bean>
<!-- Destination Connection factory -->
<bean id="customerOrderXAConnectionFactoryDestination" class="org.springframework.jndi.JndiObjectFactoryBean"
lazy-init="true">
<property name="jndiTemplate" ref="jndiTemplateDestination" />
<property name="jndiName"
value="${destination.java.naming.factory.connection}" />
<property name="lookupOnStartup" value="false" />
<property name="proxyInterface" value="javax.jms.XAConnectionFactory" />
</bean>
<bean id="connectionFactoryDestination" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
init-method="init" destroy-method="close">
<property name="poolSize" value="100" />
<property name="uniqueResourceName" value="esb" />
<property name="xaConnectionFactory" ref="customerOrderXAConnectionFactoryDestination" />
<property name="localTransactionMode" value="true" />
</bean>
<bean id="ddr" class="com.adeo.transverse.jms.forwarder.customerorder.DynamicDestinationResolver" />
<bean id="userCredentialsConnectionFactoryDestination"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter" lazy-init="true">
<property name="targetConnectionFactory">
<ref bean="connectionFactoryDestination" />
</property>
<property name="username" value="${destination.username}" />
<property name="password" value="${destination.passwd}" />
</bean>
Here's the integration part :
<!-- In bridge -->
<jms:message-driven-channel-adapter
id="StoreStockMotionSourceJmsAdapter" channel="bridgeChannelStoreStockMotionEnricher"
container="jmsContainerSourceStoreStockMotion" />
<!-- Channel -->
<si:channel id="bridgeChannelStoreStockMotionEnricher" />
<jms:outbound-channel-adapter id="StoreStockMotionDestinationJmsAdapter"
channel="bridgeChannelStoreStockMotionEnricher" jms-template="jmsTemplateStoreStockMotionDestination" />
<bean id="jmsTemplateStoreStockMotionDestination" class="org.springframework.jms.core.JmsTemplate">
<property name="transactionManager" ref ="transactionManager"/>
<property name="connectionFactory" ref="userCredentialsConnectionFactoryDestination" />
<property name="defaultDestinationName" value="${StoreStockMotion.destination.topic}" />
<property name="defaultDestination" ref="StoreStockMotionDestinationTopic" />
<property name="pubSubDomain" value="true"/>
</bean>
<!-- Topic JMS for published message -->
<bean id="StoreStockMotionDestinationTopic" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
<property name="jndiTemplate">
<ref bean="jndiTemplateDestination" />
</property>
<property name="jndiName">
<value>${StoreStockMotion.destination.topic}</value>
</property>
</bean>
<!-- Topic JMS for Subscribing Message -->
<bean id="jmsContainerSourceStoreStockMotion"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
lazy-init="true">
<property name="connectionFactory" ref="connectionFactorySource" />
<property name="destinationName" value="${StoreStockMotion.source.topic}" />
<property name="subscriptionDurable" value="true" />
<!-- 2 is client acknowledge -->
<property name="sessionAcknowledgeMode" value="2" />
<property name="durableSubscriptionName" value="${StoreStockMotion.source.subname}" />
<property name="sessionTransacted" value="false" />
<property name="pubSubDomain" value="true"/>
</bean>
Source and Destination are both encapsulated in XA connection factories and transactionManager handles the two transactions. Any idea what's missing ?

Camel-Mybatis Open session Exception

I'm using Camel-Mybatis version 2.12.0.redhat-610379, when we trying to start the bundle thru karaf container the following exception throws. Please advice.
org.apache.ibatis.exceptions.PersistenceException:
Error opening session. Cause: java.lang.NullPointerException
Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)[280:org.mybatis.mybatis:3.2.5]
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:88)[280:org.mybatis.mybatis:3.2.5]
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:43)[280:org.mybatis.mybatis:3.2.5]
at org.apache.camel.component.mybatis.MyBatisProducer.process(MyBatisProducer.java:51)[282:org.apache.camel.camel-mybatis:2.12.0.redhat-611412]
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:110)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:279)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:56)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:166)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processByErrorHandler(TransactionErrorHandler.java:218)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:99)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:112)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processByErrorHandler(TransactionErrorHandler.java:218)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler$1.doInTransactionWithoutResult(TransactionErrorHandler.java:181)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:33)[149:org.apache.servicemix.bundles.spring-tx:3.2.9.RELEASE_1]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)[149:org.apache.servicemix.bundles.spring-tx:3.2.9.RELEASE_1]
at org.apache.camel.spring.spi.TransactionErrorHandler.doInTransactionTemplate(TransactionErrorHandler.java:174)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processInTransaction(TransactionErrorHandler.java:134)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:103)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:112)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:147)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:69)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at java.util.TimerThread.mainLoop(Timer.java:555)[:1.7.0_01]
at java.util.TimerThread.run(Timer.java:505)[:1.7.0_01]
Caused by: java.lang.NullPointerException
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:83)[280:org.mybatis.mybatis:3.2.5]
... 32 more
Bean.xml
<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value=""/>
<property name="user" value=""/>
<property name="password" value="" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<argument ref="ds" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="mybatisConfig" class="org.springframework.core.io.ClassPathResource">
<argument value="SqlMapConfig.xml" />
</bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" ref="mybatisConfig"/>
<property name="mapperLocations">
<array value-type="org.springframework.core.io.Resource">
<bean class="org.springframework.core.io.ClassPathResource">
<argument value="mappings/QueryMessaging.xml" />
</bean>
</array>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.apache.ibatis.session.SqlSessionFactory" factory-ref="sqlSessionFactoryBean"
factory-method="getObject" />
<bean id="myBatis" class="org.apache.camel.component.mybatis.MyBatisComponent">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
Connections and configurations are created properly, the bug I have made was in bean.xml i have used myBatis bean id, and camel route i have type as mybatis, due to case-sensitive, no environment was created, sorry for that.

Issue with CachingConnectionFactory and DefaultMessageListenerContainer

It is mentioned in the documentation of DefaultMessageListenerContainer class that it is not recommended to use CachingConnectionFactory with dynamic scaling. While searching, I have encountered following link:
Why DefaultMessageListenerContainer should not use CachingConnectionFactory?
Here found a comment from Gary Russell that
the problem is with caching consumers when using variable concurrency in the container; we can end up with a live consumer "stuck" in the cache".
We have used DefaultMessageListenerContainer and CachingConnectionFactory together so this is surely a problem from above link.
We are encountering problems with our application having following behaviour:
TCP ZeroWindow network congestion
TCP RESET from application server to MQ
DB connection grows during the issue while different transactions halt
Messages in certain queues gets built up
We have following code configuration :
In ibmmq-context.xml file:
<!-- WebSphere MQ Connection Factory -->
<bean id="appMqConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
<property name="hostName">
<value>${ibmmq.ip}</value>
</property>
<property name="port">
<value>${ibmmq.port}</value>
</property>
<property name="queueManager">
<value>${ibmmq.queuemanager}</value>
</property>
<property name="channel">
<value>${ibmmq.channel}</value>
</property>
<property name="clientReconnectOptions">
<util:constant static-field="com.ibm.msg.client.wmq.WMQConstants.WMQ_CLIENT_RECONNECT"/>
</property>
<property name="transportType" ref="appTransport"/>
</bean>
<!-- A cached connection -->
<bean id="appCachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="appMqConnectionFactory"/>
<property name="sessionCacheSize" value="${jms.session.cachesize}"/>
</bean>
<!-- Use native MQ classes. -->
<bean id="appTransport" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField">
<value>com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP</value>
</property>
</bean>
In jms-context file:
<bean id="bankListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="destination" ref="transactionResponseDestination" />
<property name="messageListener" ref="thirdpartyService" />
<property name="autoStartup" value="false"/>
<property name="taskExecutor" ref="listenerExecutor"/>
<property name="concurrency" value="20-30"/>
</bean>
There are 6 such listeners like bankListener and each of the listeners has concurrency value, varies from 10-40
<bean id="listenerExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="maxPoolSize" value="140"/>
<property name="corePoolSize" value="100"/>
<property name="queueCapacity" value="30"/>
<property name="threadNamePrefix" value="jms-listener-task-"/>
<property name="threadGroupName" value="jms-listener-tasks"/>
</bean>
and jms-context.xml file uses ibmmq-context.xml file.
And to note, we have used IBM MQ 7.1, Spring 4.2.8, spring-integration-core as 4.3.1.RELEASE and JBoss EAP 6.4.10
We are planning to fix this by following way:
<bean id="bankListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="appMqConnectionFactory" />
<property name="destination" ref="transactionResponseDestination" />
<property name="messageListener" ref="thirdpartyService" />
<property name="autoStartup" value="false"/>
<property name="taskExecutor" ref="listenerExecutor"/>
<property name="concurrency" value="20-30"/>
</bean>
My request:
Please review the configuration and let me know is there anything else to be changed.
Could you please also explain our application behaviour(above 4 points - a to d) with our current configuration with CachingConnectionFactory and DefaultMessageListenerContainer
Thanks in advance for your help.
Try setting:
cachingConnectionFactory.setCacheConsumers(false);
Or in Spring it should be:
<bean id="appCachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
...
<property name="cacheConsumers" value="false"/>
...
</bean>

ReloadingPropertyPlaceholderConfigurer

For some reason the ReloadablePropertiesFactoryBean doens't seem to do what I expect. When I change a property in the test.properties file I get a log message saying:
9979 [timer] INFO com.krest.core.properties.ReloadablePropertiesFactoryBean - Reloading Properties...
But for some reason nothing happens. The old property value is still set on my test bean. Does anybody know why this is? I use Spring 3 and my configuration looks like this:
<bean id="configproperties"
class="com.krest.core.properties.ReloadablePropertiesFactoryBean">
<property name="location"
value="classpath:test.properties" />
</bean>
<bean id="propertyConfigurer"
class="com.krest.core.properties.ReloadingPropertyPlaceholderConfigurer">
<property name="properties" ref="configproperties" />
<property name="reloadingPlaceholderPrefix" value="rel{" />
<property name="reloadingPlaceholderSuffix" value="}" />
</bean>
<bean id="mybean" class="nl.mycompany.TestBean">
<property name="message" value="rel{timer-delay}" />
</bean>
<!-- regularly reload property files. -->
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<bean id="reloadProperties"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="period" value="1000" />
<property name="runnable">
<bean class="com.krest.core.properties.ReloadConfiguration">
<property name="reconfigurableBeans">
<list>
<ref bean="configproperties" />
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>

method-invoking Spring bean

I've declared the following bean in my Spring config
<bean id="templateCacheClearingTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="5000" />
<property name="period" value="5000" />
<property name="timerTask">
<bean class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="templateMailService" />
<property name="targetMethod" value="clearCache" />
</bean>
</property>
</bean>
This should cause the clearCache() method of the templateMailService bean to be invoked every 5000ms, but nothing appears to be happening. Am I missing something?
Cheers,
Don
I think you need:
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="templateCacheClearingTask"/>
</list>
</property>
</bean>
In addition to what you already have.

Categories