commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jens Viebig" <js...@gmx.de>
Subject [VFS] FTPClientWrapper Broken Pipe
Date Thu, 01 Sep 2005 16:09:59 GMT
Hello List,
i'm using VFS to regulary check some files on an FTP server. This works fine for a long time,
but after a while the check crashes with the following stacktrace:

org.apache.commons.vfs.FileSystemException: Could not determine the type of file ftp://user:password@myserver.com/myfile.txt.
        at org.apache.commons.vfs.provider.AbstractFileObject.attach()V(Optimized Method)
        at org.apache.commons.vfs.provider.AbstractFileObject.exists()Z(AbstractFileObject.java:391)
        at my.class.Something.toDo(Unknown Source)
        at java.lang.Thread.run()V(Unknown Source)
        at java.lang.Thread.startThreadFromVM(Ljava.lang.Thread;)V(Unknown Source)
Caused by: java.net.SocketException: Broken pipe
        at jrockit.net.SocketNativeIO.write(IIIZ)I(Unknown Source)
        at jrockit.net.SocketNativeIO.write(III)I(Unknown Source)
        at jrockit.io.NativeIO.write(Ljava.io.FileDescriptor;II)I(Optimized Method)
        at java.net.AbstractSocketImpl$2.write(II)V(Optimized Method)
        at jrockit.io.NativeIOOutputStream.write([BII)V(Optimized Method)
        at java.io.BufferedOutputStream.flushBuffer()V(Optimized Method)
        at java.io.BufferedOutputStream.write(I)V(Optimized Method)
        at org.apache.commons.net.telnet.Telnet._sendByte(I)V(Optimized Method)
        at org.apache.commons.net.telnet.TelnetOutputStream.write(I)V(Optimized Method)
        at org.apache.commons.net.io.ToNetASCIIOutputStream.write([BII)V(Optimized Method)
        at sun.nio.cs.StreamEncoder$CharsetSE.writeBytes()V(StreamEncoder.java:325)
        at sun.nio.cs.StreamEncoder$CharsetSE.implWrite([CII)V(Optimized Method)
        at sun.nio.cs.StreamEncoder.write([CII)V(StreamEncoder.java:136)
        at java.io.OutputStreamWriter.write([CII)V(OutputStreamWriter.java:191)
        at java.io.BufferedWriter.flushBuffer()V(BufferedWriter.java:107)
        at java.io.BufferedWriter.flush()V(BufferedWriter.java:228)
        at org.apache.commons.net.ftp.FTP.sendCommand(Ljava.lang.String;Ljava.lang.String;)I(Optimized
Method)
        at org.apache.commons.net.ftp.FTP.sendCommand(ILjava.lang.String;)I(Optimized Method)
        at org.apache.commons.net.ftp.FTP.port(Ljava.net.InetAddress;I)I(Optimized Method)
        at org.apache.commons.vfs.provider.ftp.FTPClientWrapper.listFiles(Ljava.lang.String;Ljava.lang.String;)[Lorg.apache.commons.net.ftp.FTPFile;(Optimized
Method)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.doGetChildren()V(Optimized Method)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getChildFile(Ljava.lang.String;Z)Lorg.apache.commons.net.ftp.FTPFile;(Optimized
Method)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getInfo(Z)V(Optimized Method)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.doAttach()V(Optimized Method)
        ... 6 more

When it comes to that error, the filesystem provider never recovers from that crash and all
actions on files on the same ftp server fail. The ftp server works fine, i can connect fine
from the commandline. it seems that the VFS ftp provider tries to reuse that old damaged connection,
i don't see a new attempt to login in my ftp server log. There is no connection from VFS to
the ftp server.

I looked in the source code of FTPClientWrapper, and tracked the error down to the listFiles
function:

...
    public FTPFile[] listFiles(String key, String relPath) throws IOException
    {
        try
        {
            return getFtpClient().listFiles(key, relPath);
        }
        catch (FTPConnectionClosedException e)
        {
            disconnect();
            return getFtpClient().listFiles(key, relPath);
        }
    }
...

the FTPClient of commons.net throws FTPConnectionClosedException and IOException. if a FTPConnectionClosedException
is thrown everything is fine, the old connection is closed and a new one is created. If a
more general IOException is thrown the connection is not closed and not set to null, so the
FTPClientWrapper tries to use it again. Normally isConnected() should fail then, but it seems
that it still returns true und is a weak test. I suggest that the connection should also be
disconnected and set to null on more general errors, if there is an IOException there is a
big chance that the connection is not usable anymore.

Maybe like this:

    public FTPFile[] listFiles(String key, String relPath) throws IOException
    {
        try
        {
            return getFtpClient().listFiles(key, relPath);
        }
        catch (FTPConnectionClosedException e)
        {
            disconnect();
            return getFtpClient().listFiles(key, relPath);
        }
        catch (IOException ie)
        {
            disconnect();
            throw ie;
        }
    }

This fix should be applied to all functions in FTPClientWrapper

Maybe you have a better approach on fixing this issue ?
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message