When throwing a significant amount of load to an ActiveMQ queue it seems to enqueue/dequeue messages as it's supposed to, but the storage remains full.
This causes the producer to block after some time, when the storage gets to 100%, which in turn causes the application to stop responding to requests.
This is the relevant activeMQ Spring configuration that we're using:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- =====================================================
Broker Configuration
===================================================== -->
<broker id="appEmbeddedBroker"
xmlns="http://activemq.apache.org/schema/core"
brokerName="${msg.embedded.broker.name}"
persistent="true"
dataDirectory="${msg.embedded.broker.data.directory}"
useJmx="true" >
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" >
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<managementContext>
<managementContext connectorPort="${msg.embedded.broker.jmx.port}" createConnector="false"/>
</managementContext>
<persistenceAdapter>
<levelDB directory="${msg.embedded.broker.db.directory}" />
</persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="10"/>
</memoryUsage>
<storeUsage>
<storeUsage limit="${msg.embedded.broker.system.usage.store.usage}"/> <!-- Configured for 200Mb -->
</storeUsage>
<tempUsage>
<tempUsage limit="${msg.embedded.broker.system.usage.temp.usage}"/> <!-- Configured for 40Mb -->
</tempUsage>
</systemUsage>
</systemUsage>
<plugins>
<!-- Configure authentication; Username, passwords and groups -->
<simpleAuthenticationPlugin anonymousAccessAllowed="false">
<users>
<authenticationUser username="app" password="${msg.embedded.broker.app.password}"
groups="users"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
<transportConnectors>
<transportConnector name="tcp" uri="tcp://0.0.0.0:${msg.embedded.broker.port}?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
</broker>
<!-- =====================================================
Client Connections
===================================================== -->
<bean id="embeddedAmqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="appEmbeddedBroker" >
<property name="brokerURL" value="${msg.embedded.broker.url}" />
<property name="userName" value="${msg.embedded.client.app.username}" />
<property name="password" value="${msg.embedded.broker.app.password}" />
</bean>
<bean id="embeddedAmqPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" >
<property name="connectionFactory" ref="embeddedAmqConnectionFactory" />
<property name="maxConnections" value="${msg.embedded.client.connection.pool.max}" />
</bean>
When querying the beans:
$>get QueueSize EnqueueCount DequeueCount
#mbean = org.apache.activemq:brokerName=app-embedded,destinationName=the.queue.name.local,destinationType=Queue,type=Broker:
QueueSize = 0;
EnqueueCount = 17821;
DequeueCount = 17821;
And:
#mbean = org.apache.activemq:brokerName=app-embedded,type=Broker:
StoreLimit = 209715200;
StorePercentUsage = 100;
TempLimit = 41943040;
TempPercentUsage = 0;
So, the question would be: Why if all messages are getting dequeued we still see 100% of storage usage?
There can be many reasons for this depending on you broker configuration and usage. First thing to check is what the contents of your DLQ are, then look on the console for other destinations that are holding onto messages. Due to the way things are propagated through the KahaDB journal logs it is possible that they create a chain that cannot be broken until you purge some other Queues or rollback any Transactions that are still inflight etc.
There is a guide on the ActiveMQ site that covers how to start debugging the situation that should help get you started.
Also try running the latest broker release, there are fixes that have gone into these components that try and address these sorts of situations.
Related
I created the flow below and it's working normally but all the time this information is printed in the log file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-5.2.xsd
http://www.springframework.org/schema/integration/http
http://www.springframework.org/schema/integration/http/spring-integration-http-5.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<task:executor id="taskExecutorRecursaoRendaVariavel" pool-size="15-20" queue-capacity="100"/>
<task:executor id="taskExecutorProcessamentoRendaVariavel" pool-size="15-20" queue-capacity="100"/>
<task:executor id="taskExecutorSplitterRendaVariavel" pool-size="15-20" queue-capacity="100"/>
<int:channel id="xxx-consolidador-movimentacao-renda-variavel"/>
<int:publish-subscribe-channel id="xxx-consolidador-splitter-recursao-renda-variavel" task-executor="taskExecutorSplitterRendaVariavel"/>
<int:channel id="xxx-consolidador-channel-segrega-renda-variavel"/>
<int:publish-subscribe-channel id="xxx-consolidador-splitter-renda-variavel-recursao-movimentacao" task-executor="taskExecutorRecursaoRendaVariavel"/>
<int:publish-subscribe-channel id="xxx-consolidador-splitter-renda-variavel-processa-movimentacao" task-executor="taskExecutorProcessamentoRendaVariavel"/>
<int:channel id="xxx-consolidador-direct-channel-movimentacao-renda-variavel"/>
<int:channel id="xxx-consolidador-request-ativo-renda-variavel"/>
<int:channel id="xxx-consolidador-request-movimentacao-renda-variavel"/>
<int:channel id="xxx-consolidador-request-notifica-renda-variavel"/>
<int:channel id="xxx-consolidador-filter-channel-renda-variavel"/>
<int-http:outbound-gateway
url="${xxxx.xxxxx.movimentacao-rendavariavel}?startDate={dtInitPosicao}&endDate={dtenddate}&page={page}&recordPerPage=${RECORDS_PER_PAGE:250}&cblc={cblc}&cpfCnpj={cpf}"
http-method="GET"
expected-response-type="br.com.xxxxx.ciar.xxx.xxx.xxx.integration.response.ResponseRendaVariavelMovimentacao"
request-channel="xxx-consolidador-movimentacao-renda-variavel"
reply-channel="xxx-consolidador-splitter-recursao-renda-variavel"
rest-template="restTemplate"
mapped-request-headers="Authorization, cpf, cblc, dtInitPosicao, dtenddate, page">
<int-http:uri-variable name="cpf" expression="headers.cpf"/>
<int-http:uri-variable name="cblc" expression="headers.cblc"/>
<int-http:uri-variable name="dtInitPosicao" expression="headers.dtinitposicao"/>
<int-http:uri-variable name="dtenddate" expression="headers.dtenddate"/>
<int-http:uri-variable name="page" expression="headers.page"/>
</int-http:outbound-gateway>
<int:splitter input-channel="xxx-consolidador-splitter-recursao-renda-variavel"
output-channel="xxx-consolidador-channel-segrega-renda-variavel">
<bean class="br.com.xxx.ciar.xxx.renda.variavel.integration.splitter.SplitterRecursaoRendaVariavel"/>
</int:splitter>
<int:header-value-router id="recursaoRendaVariavel" input-channel="xxx-consolidador-channel-segrega-renda-variavel"
header-name="recursao" resolution-required="false">
<int:mapping value="true" channel="xxx-consolidador-splitter-renda-variavel-recursao-movimentacao"/>
</int:header-value-router>
<int:header-value-router id="processaRendaVariavel" input-channel="agora-consolidador-channel-segrega-renda-variavel"
header-name="processa" resolution-required="false">
<int:mapping value="true" channel="xxxx-consolidador-splitter-renda-variavel-processa-movimentacao"/>
</int:header-value-router>
<int:header-filter input-channel="xxx-consolidador-splitter-renda-variavel-processa-movimentacao"
output-channel="xxx-consolidador-filter-channel-renda-variavel"
header-names="Authorization, authorization"/>
<int:splitter input-channel="xxx-consolidador-filter-channel-renda-variavel"
output-channel="xxx-consolidador-direct-channel-movimentacao-renda-variavel">
<bean class="br.com.xxx.ciar.xxxx.renda.variavel.integration.splitter.RendaVariavelMovimentacaoSplitter"/>
</int:splitter>
<int:header-value-router input-channel="xxx-consolidador-direct-channel-movimentacao-renda-variavel" header-name="type" order="1">
<int:mapping value="ativos" channel="xxx-consolidador-request-ativo-renda-variavel"/>
</int:header-value-router>
<int:header-value-router input-channel="xxx-consolidador-direct-channel-movimentacao-renda-variavel" header-name="type" order="2">
<int:mapping value="posicao" channel="xxx-consolidador-request-movimentacao-renda-variavel"/>
</int:header-value-router>
<int:header-value-router input-channel="xxx-consolidador-direct-channel-movimentacao-renda-variavel" header-name="type" order="3">
<int:mapping value="notifica" channel="xxx-consolidador-request-notifica-renda-variavel"/>
</int:header-value-router>
<int-http:outbound-channel-adapter
http-method="POST"
url="${xxxx.ativos}"
channel="xxx-consolidador-request-ativo-renda-variavel"
rest-template="restTemplate"
mapped-request-headers="Authorization, DESTINO_URL">
</int-http:outbound-channel-adapter>
<int-http:outbound-channel-adapter
http-method="POST"
url="${xxxx.movimento-rendavariavel}"
channel="xxx-consolidador-request-movimentacao-renda-variavel"
rest-template="restTemplate"
mapped-request-headers="Authorization, DESTINO_URL">
</int-http:outbound-channel-adapter>
<int-http:outbound-channel-adapter
http-method="POST"
url="${xxxx.notifica}"
channel="xxx-consolidador-request-notifica-renda-variavel"
rest-template="restTemplate"
mapped-request-headers="Authorization, DESTINO_URL">
</int-http:outbound-channel-adapter>
</beans>
2021-11-05 17:55:16,811 [taskExecutorSplitterRendaVariavel-1] INFO o.s.i.d.UnicastingDispatcher - An exception was thrown by 'bean 'org.springframework.integration.config.RouterFactoryBean#6' for component 'recursaoRendaVariavel'; defined in: 'file []'; from source: ''int:header-value-router' with id='recursaoRendaVariavel''' while handling 'GenericMessage [payload=br.com.bradesco.ciar.agora.renda.variavel.integration.response.ResponseRendaVariavelMovimentacao#2a5ae9, headers={Transfer-Encoding=chunked, http_requestMethod=GET, sequenceNumber=1, processa=true, sequenceSize=2, dtenddate=20211105, Pragma=no-cache, http_statusCode=200 OK, Date=1636145712000, dtinitposicao=20211101, Cache-Control=no-cache, no-store, max-age=0, must-revalidate, cblc=161254, cpf=21333240899, http_requestUrl=http://localhost:8083/renda-variavel/xxxxxxxxxx, contentType=application/json;charset=utf-8, timestamp=1636145716810}]': No channel resolved by router 'recursaoRendaVariavel' and no 'defaultOutputChannel' defined.. Failing over to the next subscriber.
Your <int:channel id="xxx-consolidador-channel-segrega-renda-variavel"/> is a DirectChannel with a UnicastingDispatcher, which has a logic to failover to the next subscriber, if the current one has failed. The logic is like this:
if (!isLast && this.failover) {
logExceptionBeforeFailOver(ex, handler, message);
}
We log that message to inform you that this might not be an expected behavior. For example that was an accident to add another subscriber to this channel. The whole exception info is present there to let you know that your logic in the router has failed: you probably didn't expect that No channel resolved by router 'recursaoRendaVariavel' for your use-case.
From here, if you really think that your flow is doing OK failing over to the next subscriber for that router error, then you just can ignore such an INFO message in the logs or turn off INFO for org.springframework.integration at all.
I am creating a simple spring boot application(PoC) to send product id's (string) from client to server over socket using Spring integration TCP. If the server is hit with correct product data, the server will respond back with the product details which I need to print. Just need to establish a connection and get the response by sending proper data.
Please tell me what are the classes I am supposed to implement? outbound/inboud gateways,messsage channels, tcplisteners? Should I go with xml configuration or annotations? I am new to SI and would be of great help if you could give me an idea on how to implement it.
Here is my updated integration xml.
<int-ip:tcp-connection-factory id="client" type="client" host="XX.XX.XX.99" port="9XXX" single-use="true" so-timeout="10000" />
<int:channel id="input"/>
<int-ip:tcp-outbound-gateway id="outGateway" request-channel="input" reply-channel="clientBytes2StringChannel" connection-factory="client" request-timeout="10000" reply-timeout="10000"/>
<int:object-to-string-transformer id="clientBytes2String" input-channel="clientBytes2StringChannel"/>
<int:service-activator input-channel="clientBytes2StringChannel" ref="echoService" method="test"/>
<bean id="echoService" class="org.springframework.integration.samples.tcpclientserver.EchoService"/>
<int:channel id="toSA"/>
But this still prints the echoed result. Also, when I call getHost on abstractClientConnectionfactory from main class, its showing "localhost". How can I confirm if the connection is active?
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client" type="client" host="xx.xx.xx.99"
port="9xxx"
single-use="false" so-timeout="300000" using-nio="false"
so-keep-alive="true" serializer="byteArrayRawSerializer"
deserializer="byteArrayRawSerializer"/>
<bean id="byteArrayRawSerializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayRawSerializer" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="responseBytes2StringChannel"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000" />
<int:object-to-string-transformer id="clientBytes2String"
input-channel="responseBytes2StringChannel" output-channel="toSA"/>
<int:service-activator input-channel="toSA" ref="echoService" method="test"/>
<bean id="echoService" class="org.springframework.integration.samples.tcpclientserver.EchoService"/>
<int:channel id="toSA"/>
<int:transformer id="errorHandler" input-channel="errorChannel" expression="payload.failedMessage.payload + ':' + payload.cause.message"/>
<int:channel id="responseBytes2StringChannel"></int:channel>
**** Update SI xml ****
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="objectIn"/>
<int:channel id="objectIn" />
<int-ip:tcp-connection-factory id="client"
type="client"
host="xx.xx.xx.99"
port="9xxx"
single-use="true"
so-timeout="50000"
using-nio="false"
so-keep-alive="true"/>
<!--
serializer="byteArrayLengthSerializer"
deserializer="byteArrayLengthSerializer"
<bean id="byteArrayLengthSerializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayLengthHeaderSerializer " />
-->
<int:payload-serializing-transformer input-channel="objectIn" output-channel="objectOut"/>
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="objectOut"
reply-channel="bytesIn"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000"
/>
<int:payload-deserializing-transformer input-channel="bytesIn" output-channel="objectOut" />
<int:object-to-string-transformer id="clientBytes2String"
input-channel="objectOut" output-channel="toSA"/>
<int:service-activator input-channel="toSA" ref="echoService" method="test"/>
<bean id="echoService" class="org.springframework.integration.samples.tcpclientserver.EchoService"/>
<int:channel id="objectOut"/>
<int:channel id="toSA"/>
<int:channel id="bytesIn"/>
I suggest you to go the Documentation route first: https://docs.spring.io/spring-integration/docs/current/reference/html/ip.html to investigate what Spring Integration provides for you in regards of TCP/IP. Then it would be great to jump into samples project to see what we suggest for configuration and usage options: https://github.com/spring-projects/spring-integration-samples
As a follow up to the question -
Same file gets picked up again and again in spring-ftp but with different names
I have the following configuration in my application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:file="http://www.springframework.org/schema/integration/file"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xmlns:int-ftp="http://www.springframework.org/schema/integration/ftp"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/ftp
http://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<int:poller id="poller" task-executor="synchTaskExecutor" default="true" fixed-delay="1000" />
<beans:bean id="ftpClientFactory"
class="com.everge.springframework.integration.ftp.session.EvergeFtpSessionFactory">
<beans:property name="host" value="111.93.128.170"/>
<beans:property name="port" value="21"/>
<beans:property name="username" value="singha"/>
<beans:property name="password" value="singha16"/>
<beans:property name="clientMode" value="2"></beans:property>
</beans:bean>
<beans:bean id="ftpOutClientFactory"
class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
<beans:property name="host" value="111.93.128.170"/>
<beans:property name="port" value="21"/>
<beans:property name="username" value="singha"/>
<beans:property name="password" value="singha16"/>
<beans:property name="clientMode" value="2"></beans:property>
</beans:bean>
<beans:bean id="synchTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<beans:property name="corePoolSize" value="1"></beans:property>
<beans:property name="maxPoolSize" value="1"></beans:property>
<beans:property name="queueCapacity" value="1"></beans:property>
</beans:bean>
<beans:bean id="pqqFtpClientFactory"
class="com.everge.springframework.integration.ftp.session.PqqEvergeFtpSessionFactory">
<beans:property name="host" value="111.93.128.170"/>
<beans:property name="port" value="21"/>
<beans:property name="username" value="singha"/>
<beans:property name="password" value="singha16"/>
<beans:property name="clientMode" value="2"></beans:property>
</beans:bean>
<int:channel id="ftpChannel">
<int:queue/>
</int:channel>
<beans:bean id="acceptAllFileListFilter" class="com.everge.file.processing.EvergeFileListFilter"/>
<beans:bean id="pqqHandler" class="com.everge.pqq.PqqFileHandler">
<beans:property name="config" ref="baseConfig"></beans:property>
</beans:bean>
<beans:bean id="handler" scope="prototype" class="com.everge.integration.client.FileHandler">
<beans:property name="config" ref="baseConfig"></beans:property>
</beans:bean>
<beans:bean id="baseConfig" class="com.everge.config.BaseConfig" />
<beans:bean id="ftpSplitter" class="com.everge.service.FtpSplitter" />
<beans:bean id="fileSplitter" class="com.everge.file.processing.FileSplitter" />
<int-ftp:outbound-channel-adapter id="notifFtpOutBound"
channel="pl"
remote-directory="/ADPWG/PRCSD1"
session-factory="ftpOutClientFactory" auto-startup="true">
<int-ftp:request-handler-advice-chain>
<int:retry-advice />
</int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="pqqOutputFileChannel"
remote-directory="/ADPWG/PRCSD"
session-factory="ftpOutClientFactory" auto-startup="true">
<int-ftp:request-handler-advice-chain>
<int:retry-advice />
</int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>
<file:inbound-channel-adapter prevent-duplicates="false" id="filesIn1" directory="file:/Users/abhisheksingh/ddrive/everge_ws/f" auto-startup="true">
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="1000"></int:poller>
</file:inbound-channel-adapter>
<int:service-activator input-channel="filesIn1" ref="handler" />
<file:inbound-channel-adapter prevent-duplicates="false" id="pqqInputFileChannel" directory="file:/Users/abhisheksingh/ddrive/everge_ws/pqqReq" auto-startup="true">
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="1000" />
</file:inbound-channel-adapter>
<int:service-activator input-channel="pqqInputFileChannel" ref="pqqHandler" />
<file:inbound-channel-adapter id="pqqOutputFileChannel" directory="/Users/abhisheksingh/ddrive/everge_ws/pqqResp">
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="10000" />
</file:inbound-channel-adapter>
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpChannel"
session-factory="ftpClientFactory"
auto-create-local-directory="true"
delete-remote-files="false"
local-filter="acceptAllFileListFilter"
local-directory="file:/Users/abhisheksingh/ddrive/everge_ws/f" auto-startup="true" >
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="1000" />
</int-ftp:inbound-channel-adapter>
<int-ftp:inbound-channel-adapter id="pqqFtpInbound"
channel="ftpChannel"
session-factory="pqqFtpClientFactory"
auto-create-local-directory="true"
delete-remote-files="false"
local-filter="acceptAllFileListFilter"
local-directory="file:/Users/abhisheksingh/ddrive/everge_ws/pqqReq" auto-startup="true" >
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="1000" />
</int-ftp:inbound-channel-adapter>
<file:inbound-channel-adapter id="pl" directory="file:/Users/abhisheksingh/ddrive/everge_ws/notifFile" auto-startup="true">
<int:poller id="poller" task-executor="synchTaskExecutor" fixed-delay="1000" />
</file:inbound-channel-adapter>
</beans:beans>
So there is a ftp location which I poll and the polled file gets placed at the following directory on my local machine-
/Users/abhisheksingh/ddrive/test/f
Now sometimes because I found a bug and have to fix it, I stop the tomcat server. I delete the files from my local so that next time I start my server , the same file can be polled again. But I find that the same file gets polled again. My server is stopped! This should not happen as far as I know. Thats why I have posted my application.xml to know if there is something here which keeps the threads hanging. Or is it that the spring-integration-ftp starts a daemon thread which does not depend on the application. Please let me solve this riddle.
I see the following exception in the tomcat logs -
Feb 17, 2017 11:49:24 PM org.apache.catalina.loader.WebappClassLoaderBase loadClass
INFO: Illegal access: this web application instance has been stopped already. Could not load UNIX Type: L8. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1777)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:88)
at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2263)
at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2046)
at org.springframework.integration.ftp.session.FtpSession.list(FtpSession.java:70)
at org.springframework.integration.ftp.session.FtpSession.list(FtpSession.java:43)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer$1.doInSession(AbstractInboundFileSynchronizer.java:236)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer$1.doInSession(AbstractInboundFileSynchronizer.java:232)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:435)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:232)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:193)
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:59)
at org.springframework.integration.endpoint.AbstractMessageSource.receive(AbstractMessageSource.java:134)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:224)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:245)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
I am pretty much sure at this point that the spring-integration ftp poller does not let the tomcat stop properly.
I did investigate more using jvisualvm. I see that there are task-scheduler threads started which do not close with ./shutdown.sh call to stop the tomcat.
Interesting thing to observe is that if I remove either of the pl or pqqOutputFileChannel adapter, these schedulers dont get created.
Here is the structure of my ear file -
Following is the log which keeps on rolling in the log file even when
shutdown has been called on the tomcat -
541576 DEBUG o.s.i.c.PublishSubscribeChannel - postSend (sent=true) on
channel 'errorChannel', message: ErrorMessage
[payload=org.springframework.core.task.TaskRejectedException: Executor
[java.util.concurrent.ThreadPoolExecutor#6d6033da[Running, pool size =
1, active threads = 0, queued tasks = 0, completed tasks = 1114]] did
not accept task:
org.springframework.integration.util.ErrorHandlingTaskExecutor$1#570e117d,
headers={id=71d77a8b-17ea-7011-3cb3-ddbf7591321f,
timestamp=1487870801603}] 541575 DEBUG o.s.i.c.PublishSubscribeChannel
- postSend (sent=true) on channel 'errorChannel', message: ErrorMessage
[payload=org.springframework.core.task.TaskRejectedException: Executor
[java.util.concurrent.ThreadPoolExecutor#6d6033da[Running, pool size =
1, active threads = 0, queued tasks = 1, completed tasks = 1113]] did
not accept task:
org.springframework.integration.util.ErrorHandlingTaskExecutor$1#44210f79,
headers={id=74a26d65-4b42-da1f-cdf1-b77fea8bfdb7,
timestamp=1487870801603}] 541576 ERROR o.s.i.handler.LoggingHandler -
org.springframework.core.task.TaskRejectedException: Executor
[java.util.concurrent.ThreadPoolExecutor#6d6033da[Running, pool size =
1, active threads = 0, queued tasks = 1, completed tasks = 1113]] did
not accept task:
org.springframework.integration.util.ErrorHandlingTaskExecutor$1#7d7cc2a4
at
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:296)
at
org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at
org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at
org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at
org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745) Caused by:
java.util.concurrent.RejectedExecutionException: Task
org.springframework.integration.util.ErrorHandlingTaskExecutor$1#7d7cc2a4
rejected from
java.util.concurrent.ThreadPoolExecutor#6d6033da[Running, pool size =
1, active threads = 0, queued tasks = 1, completed tasks = 1113] at
java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at
java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at
java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:293)
... 11 more
**541576 DEBUG o.s.i.c.PublishSubscribeChannel - postSend (sent=true) on channel 'errorChannel', message: ErrorMessage
[payload=org.springframework.core.task.TaskRejectedException: Executor
[java.util.concurrent.ThreadPoolExecutor#6d6033da[Running, pool size =
1, active threads = 0, queued tasks = 1, completed tasks = 1113]] did
not accept task:
org.springframework.integration.util.ErrorHandlingTaskExecutor$1#7d7cc2a4,
headers={id=26e6de67-2b70-cd7d-0c64-d21e1f8d1726,
timestamp=1487870801603}] 541611 DEBUG
c.e.s.i.f.s.PqqEvergeFtpSessionFactory - Connected to server
[111.93.128.170:21] 541638 INFO
c.e.s.i.f.s.PqqEvergeFtpSessionFactory - Inside
postProcessClientAfterConnect of PqqEvergeFtpSessionFactory 541778
INFO o.s.i.ftp.session.FtpSession - File has been successfully
transferred from: TEST4.PQQ 541778 DEBUG
o.s.i.f.i.FtpInboundFileSynchronizer - 1 files transferred 541779 INFO
c.e.f.p.EvergeFileListFilter - Check if the file has already been
processed /Users/abhisheksingh/ddrive/everge_ws/pqqArchive/TEST4.PQQ
541779 INFO c.e.f.p.EvergeFileListFilter - Archive file name is
541779 INFO c.e.f.p.EvergeFileListFilter - Input file name is TEST4
541779 INFO c.e.f.p.EvergeFileListFilter - Archive file name is TEST4
541779 INFO c.e.f.p.EvergeFileListFilter - Input file name is TEST4
541779 INFO c.e.f.p.EvergeFileListFilter - The file is already
processed TEST4 541779 ERROR c.e.f.p.EvergeFileListFilter - PQQ file
has already been processed. 541779 DEBUG
o.s.i.e.SourcePollingChannelAdapter - Received no Message during the
poll, returning 'false' 541974 DEBUG
o.s.i.e.SourcePollingChannelAdapter - Received no Message during the
poll, returning 'false'
Camel Version: 2.12.2,
CXF Version: 2.7,
Apache Tomcat: 7
I have the following camel-cxf.xml :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s0="http://www.huawei.com/bme/cbsinterface/cbs/businessmgr"
xmlns:s1="http://www.huawei.com/bme/cbsinterface/cbs/accountmgr"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<cxf:cxfEndpoint id="oneEndpoint"
address="${endpoint.address}"
serviceName="s1:WebService"
serviceClass="WebserviceClass"
endpointName="s1:WebSericePort_http"
wsdlURL="classpath:wsdl/WebService.wsdl">
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
<ref bean="setSoapVersionInterceptor"/>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="loggingInInterceptor" />
<ref bean="setSoapVersionInterceptor"/>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<http-conf:conduit name="*.http-conduit">
<http-conf:client
Connection="Keep-Alive"
ConnectionTimeout="60000"
ReceiveTimeout="90000"/>
</http-conf:conduit>
</beans>
In my camel-context I have two processors that use the cxf endpoint to invoke two different operations. To do that I use a producerTemplate which uses "cxf:bean:oneEndpoint" as a uri.
The project is a web application deployed in Tomcat 7.
The processors consume from two different queues. After deployment both queues are propagated with a message. The problem is that one of the processors will throw an exception upon invoking the send method on the producer template. The other will work fine. The exception is:
org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint:
cxf://bean:oneEndpoint due to: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oneEndpoint': Initialization of bean failed;
nested exception is java.lang.IllegalStateException: Could not register object [org.apache.cxf.bus.spring.SpringBus#4b0af74c] under bean name 'cxf':
there is already object [org.apache.cxf.bus.spring.SpringBus#24c0fe59] bound
Full stacktrace can be found here: http://pastebin.com/cDsQZ9r3
The second time the queues receive a message at the same time, everything works fine.
Any ideas?
PS. My web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/META-INF/spring/*.xml</param-value>
</context-param>
</web-app>
Routes & Processors:
<route id="route1" errorHandlerRef="eh1">
<from uri="{{queue1}}" />
<setHeader headerName="operationName">
<constant>Operation_1</constant>
</setHeader>
<process ref="FirstProcessor" />
<choice>
<when>
<simple>${in.headers.STATUS} == 'OK'</simple>
<inOnly uri="{{result_queue}}" />
</when>
<otherwise>
<inOnly uri="{{nok_result_queue}}" />
</otherwise>
</choice>
</route>
<route id="route2" errorHandlerRef="eh2">
<from uri="{{queue2}}" />
<setHeader headerName="operationName">
<constant>Operation_2</constant>
</setHeader>
<process ref="SecondProcessor" />
<choice>
<when>
<simple>${in.headers.STATUS} == 'OK'</simple>
<inOnly uri="{{result_queue}}" />
</when>
<otherwise>
<inOnly uri="{{nok_result_queue}}" />
</otherwise>
</choice>
</route>
<property name="producerTemplate" ref="firstProcessorTemplate" />
<property name="producerTemplateUri"
value="cxf:bean:oneEndpoint?headerFilterStrategy=#headerFilterStrategy" />
<property name="producerTemplate" ref="secondProcessorTemplate" />
<property name="producerTemplateUri"
value="cxf:bean:oneEndpoint?headerFilterStrategy=#headerFilterStrategy" />
The problem is that both queues are getting a message at the same time so both of them are trying to initialise the SpringBus at the same time.
The problem is that in BusWiringBeanFactoryPostProcessor it this code:
if (!context.containsBean(name) && (create || Bus.DEFAULT_BUS_ID.equals(name))) {
SpringBus b = new SpringBus();
ConfigurableApplicationContext cctx = (ConfigurableApplicationContext)context;
cctx.getBeanFactory().registerSingleton(name, b);
b.setApplicationContext(context);
}
So when two beans both try and initialise the SpringBus in two different threads, they can both enter the if statement at the same time leading to the exception.
The solution is to define a SpringBus in the application context so neither bean will try create a new SpringBus as one already exists.
Please share the routes definition which consumes messages from two different queues. Also you can look for option of using multicasting to have parallel processing in consuming messages from both queues and proceed with further opertion.<route>
<from uri="cxf:bean:oneEndpoint"></from>
<recipientList>
<simple>direct:${header.operationName}</simple>
<log message="Got ${header.operationName}" />
</recipientList>
</route>
Your routes (route1 and route) can be renamed as same as webservice operation name. Our code is also something similar to yours. We haven't faced problem with this approach.
I am using Infinispan L2 cache with Tomcat 6, Hibernate 4 Spring 3.5 and Junit 4.10. After integrating Infinispan cache I have encountered an exception when try to run application
Could not resolve placeholder 'hibernate.connection.password' in string value "${hibernate.connection.password}": Could not resolve placeholder 'hibernate.connection.password' in string value "${hibernate.connection.password}"
All the hibernate.properties file and spring files are in relevant places where they were in previously.
My Infinspan configuration is
<globalJmxStatistics enabled="true" jmxDomain="org.infinispan" allowDuplicateDomains="true"/>
<transport
transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport"
clusterName="infinispan-hibernate-cluster"
distributedSyncTimeout="50000"
strictPeerToPeer="false">
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>
<default>
</default>
<namedCache name="my-cache-entity">
<clustering mode="replication">
<stateRetrieval fetchInMemoryState="false" timeout="60000"/>
<sync replTimeout="20000"/>
</clustering>
<locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000"
lockAcquisitionTimeout="15000" useLockStriping="false"/>
<eviction maxEntries="10000" strategy="LRU"/>
<expiration maxIdle="100000" wakeUpInterval="5000"/>
<lazyDeserialization enabled="true"/>
<!--<transaction useSynchronization="true"
transactionMode="TRANSACTIONAL" autoCommit="false"
lockingMode="OPTIMISTIC"/>-->
<loaders passivation="false" shared="false" preload="false">
<loader class="org.infinispan.loaders.cluster.ClusterCacheLoader"
fetchPersistentState="false"
ignoreModifications="false" purgeOnStartup="false">
<properties>
<property name="remoteCallTimeout" value="20000"/>
</properties>
</loader>
</loaders>
</namedCache>
This is Spring configuration for the placeholders
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:tomcat-jdbc-pool.properties</value>
<value>classpath:hibernate.properties</value>
</list>
</property>
</bean>