I have mentioned this problem in a previous conversation but after
investigating the subject further I decided to start a new thread for this.

If some kind of problem is encountered while using ftps (I tested this using
Filezilla server by copying a file that already existed which Filezilla does
not allow), then at the next attempt to connect to the ftps server, I get
the following exception in my logfile:

13:03:27,606 | ERROR | %7Bfile%3Aext%7D | GenericFileOnCompletion          |
rg.apache.camel.processor.Logger  248 | Caused by:
[org.apache.camel.component.file.GenericFileOperationFailedException - File
operation failed: null Unconnected sockets not implemented. Code: 221]
org.apache.camel.component.file.GenericFileOperationFailedException: File
operation failed: null Unconnected sockets not implemented. Code: 221
at
org.apache.camel.component.file.remote.FtpOperations.connect(FtpOperations.java:108)[76:org.apache.camel.camel-ftp:2.4.0.SNAPSHOT]
at
org.apache.camel.component.file.remote.FtpsOperations.connect(FtpsOperations.java:40)[76:org.apache.camel.camel-ftp:2.4.0.SNAPSHOT]
at
org.apache.camel.component.file.remote.RemoteFileProducer.connectIfNecessary(RemoteFileProducer.java:170)[76:org.apache.camel.camel-ftp:2.4.0.SNAPSHOT]
at
org.apache.camel.component.file.remote.RemoteFileProducer.preWriteCheck(RemoteFileProducer.java:123)[76:org.apache.camel.camel-ftp:2.4.0.SNAPSHOT]
at
org.apache.camel.component.file.GenericFileProducer.processExchange(GenericFileProducer.java:75)[65:org.apache.camel.camel-core:2.4.0.SNAPSHOT]
at
org.apache.camel.component.file.remote.RemoteFileProducer.process(RemoteFileProducer.java:49)[76:org.apache.camel.camel-ftp:2.4.0.SNAPSHOT]
at
org.apache.camel.processor.SendProcessor$1.doInProducer(SendProcessor.java:91)[65:org.apache.camel.camel-core:2.4.0.SNAPSHOT]

I added some logging to see the actual stack trace which is:

java.net.SocketException: Unconnected sockets not implemented
        at javax.net.SocketFactory.createSocket(SocketFactory.java:104)
        at
org.apache.commons.net.SocketClient.connect(SocketClient.java:175)
        at
org.apache.camel.component.file.remote.FtpOperations.connect(FtpOperations.java:91)
        at
org.apache.camel.component.file.remote.FtpsOperations.connect(FtpsOperations.java:40)
        at
org.apache.camel.component.file.remote.RemoteFileProducer.connectIfNecessary(RemoteFileProducer.java:170)
        at
org.apache.camel.component.file.remote.RemoteFileProducer.preWriteCheck(RemoteFileProducer.java:99)
        at
org.apache.camel.component.file.GenericFileProducer.processExchange(GenericFileProducer.java:75)
        at
org.apache.camel.component.file.remote.RemoteFileProducer.process(RemoteFileProducer.java:49)

commons-net SocketClient class tries to call the socket factory's
 createSocket() method (with no parameters):

        _socket_= _socketFactory_.createSocket();
        _socket_.connect(new InetSocketAddress(hostname, port),
connectTimeout);

Then intention is to create an "unconnected socket" (hence the error
message) and then subsequently connect it. In my case, the connection
factory being used is an FTPSSocketFactory
(package org.apache.commons.net.ftp) that inherits from
SocketFactory(package javax.net). The SocketFactory class implements the
createSocket() method but throws the exception ("Unconnected sockets not
implemented").

The reason why this happens is that after having executed the
FTPSClient.execPROT() method (package org.apache.commons.net.ftp), with any
other parameter than "C" (in my case I used "P"), the socket factory is set
to an FTPSSocketFactory as follows:

            setSocketFactory(new FTPSSocketFactory(context));

After this, no connection attempt will succeed. This problem has been
introduced recently when Claus (on my initiative) added support for secure
data channel in ftps. I'm thus to blame...

I'm not sure how this should be fixed.

It's a bit strange that all the connect methods
in org.apache.commons.net.SocketClient (which is the ultimate base class of
FTPSClient) always try to create an unconnected socket first and then
connects it. If commons-net uses this pattern, then it should make sure that
all its connection factor's support unconnected sockets but the
FTPSSocketFactory dosn't. This sounds like a bug in commons-net.

Knowing that commons-net doesn't release very frequently I think we need a
workaround for this. I guess it would be possible to subclass the FTPClient
class and override all the connect methods to make sure that no attempt is
made to create unconnected sockets. We would then change the
createFtpClient() method in the FtpsEndpoint class to instantiate our own
subclass instead of an FTPSClient. Doesn't sound like a nice clean solution
though.

Any ideas?

/Bengt

Reply via email to