Announcement Announcement Module
Collapse
No announcement yet.
Trap in DefaultFtpSessionFactory Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Trap in DefaultFtpSessionFactory

    Hi,

    I have a testcase that FTP outbound channel adapter will continuously upload files to FTP Server, and another FTP inbound channel adapter will download them accordingly. It's a circular upload&download.

    but after running several hours, I found all of my thread are blocked and the circular testcase is hung without log output.
    Below is the thread dump:

    Code:
    Name: XXX-6
    State: RUNNABLE
    Total blocked: 1  Total waited: 196
    
    Stack trace: 
     java.net.PlainSocketImpl.socketAccept(Native Method)
    java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
       - locked java.net.SocksSocketImpl@79d22a1b
    java.net.ServerSocket.implAccept(ServerSocket.java:453)
    java.net.ServerSocket.accept(ServerSocket.java:421)
    org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:693)
    org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:551)
    org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1704)
    org.springframework.integration.ftp.session.FtpSession.write(FtpSession.java:79)
    org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.sendFileToRemoteDirectory(FileTransferringMessageHandler.java:222)
    org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:136)
    org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:105)
    org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:96)
    org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
    org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:175)
    org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:159)
    org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:124)
    org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:118)
    org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:100)
    org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    org.springframework.integration.endpoint.PollingConsumer.doPoll(PollingConsumer.java:70)
    org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:146)
    org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:144)
    org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:207)
    org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:52)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    java.lang.Thread.run(Thread.java:619)
    So I checked the source code in FTPClient._openDataConnection_ and I found this comment:
    // For now, let's just use the data timeout value for waiting for
    // the data connection. It may be desirable to let this be a
    // separately configurable value. In any case, we really want
    // to allow preventing the accept from blocking indefinitely.
    if (__dataTimeout >= 0)
    server.setSoTimeout(__dataTimeout);
    try {
    socket = server.accept();
    } finally {
    server.close();
    I think the lack of network timeout setting is the cause of all my thread blocking indefinitely.

    Although in official document(2.1.0.RELEASE), it mention to extend DefaultFtpSessionFactory and override two hook methods(postProcessClientAfterConnect and postProcessClientBeforeConnect), I think it's easy to ignore.


    I think It's better to add network timeout setting as a necessary attribute to Ftp Session Factory, which are easy to cause thread blocking indefinitely.
    Last edited by guoxu1231; May 25th, 2012, 09:22 AM.
Working...
X