6

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.

enter image description here

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 -

enter image description here

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'

Community
  • 1
  • 1
user3276247
  • 1,046
  • 2
  • 9
  • 24
  • I don't understand what the following means: **"But I find that the same file gets polled again. My server is stopped!"** , please clarify. It sounds like you are saying that something fetches the file from your FTP server even when your code (running in Tomcat) is stopped. This is naturally not possible. How do you even know something is fetching the file from FTP if tomcat is not running ? – nos Feb 08 '17 at 15:04
  • Because when I delete the file from the folder, I see the same file getting copied again using the same mechanism which spring-integration-ftp uses. While copying the file is names as test.txt.writing and the finally it gets written. – user3276247 Feb 08 '17 at 15:51
  • This is naturally not possible - What can I say ? I am as baffled as much as you are. Just a thought, what if the application starts a daemon thread? Will that end when the application is stopped ? – user3276247 Feb 08 '17 at 15:52
  • May it be that your application isn't tied to tomcat lifecycle? That is really something strange. Haven't seen that before. The application context close() should stop everything running – Artem Bilan Feb 08 '17 at 16:18
  • I have to restart my application to stop this behavior. – user3276247 Feb 09 '17 at 01:19
  • @user3276247 Perhaps you just think you stopped tomcat, but in reality it is still running. Keep in mind that you are not telling us the details of what you are doing, so we just have to guess. Are you stopping tomcat ? If so, how do you stop tomcat ? Have you triple checked that tomcat is not running after you tried to stop it ? If you are not stopping or restarting tomcat, what are you doing ? When you say you restart your application , do you mean you restart tomcat ? Are there any other pieces other than the tomcat server that you are running, that relates to your application ? – nos Feb 09 '17 at 08:36
  • I run ./shutdown.sh on my mac. After I do this, localhost:8080 does not render me the page. – user3276247 Feb 12 '17 at 13:14
  • However if I do grep, I still see that the thread is out there - Abhisheks-MacBook-Pro:bin abhisheksingh$ ps -aef |grep java 501 1301 1 0 6:41PM ttys000 0:17.57 /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/bin/java -Djava.util.logging.config.file=/Applications/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/Applications/tomcat/endorsed -classpath /Applications/tomcat/bin/boo.... – user3276247 Feb 12 '17 at 13:16
  • I used jvisualvm to see that there are 10 active threads with names (task-scheduler-1, 2,3... 10. Also in the tomcat logs I see - SEVERE: The web application [/integration-0.0.1-SNAPSHOT] appears to have started a thread named [task-scheduler-1] but has failed to stop it. This is very likely to create a memory leak. This pretty much sums up that spring-integration ftp poller starts threads which resist from getting stopped. – user3276247 Feb 17 '17 at 18:35
  • One more observation. Today I removed all the beans from my application.xml and kept adding them one by one. I saw that if you remove one such file:inbound-channel-adapter beans, I stop seeing threads running in jvisualvm after I stop the application. – user3276247 Feb 21 '17 at 17:31
  • Sounds like you run that `application.xml` outside of the Tomcat scope and when you `/shutdown.sh` it, the `applicationContext` isn't closed. We need to know how your application looks. – Artem Bilan Feb 22 '17 at 20:52
  • Application is a normal ear file. application.xml is a part of it. – user3276247 Feb 23 '17 at 12:44
  • I have added the snapshot of my application. – user3276247 Feb 23 '17 at 12:58

0 Answers0