In my current project at work I needed to programmatically FTP some XML documents to a remote system and so in my continuing quest to try and use every open source Java library that exists in the wild (not really, but it seems like it sometimes), this week I present to you Jakarta Commons Net. This project “.. implements the client side of many basic Internet protocols. The purpose of the library is to provide fundamental protocol access, not higher-level abstractions.” which of course includes FTP.
It’s fairly easy to get started since the JavaDocs for the FTPClient class include a couple examples, so I won’t illustrate that. The reason I’m writing is because I ran into an issue where the tests I wrote and executed on my desktop didn’t work once I deployed them to the server. Active and Passive mode are well documented elsewhere, but they don’t manifest themselves very clearly when you’re looking at a stack trace. For instance, the code to connect to an FTP server and send a file using Commons Net looks like this:
String server = "ftp.yoursite.com";
FTPClient client = new FTPClient();
client.connect(server);
client.login("username", "password");
File file = new File("testfile.txt");
InputStream is = new FileInputStream(file);
client.storeFile("testfile.txt", is);
client.disconnect();
Straightforward and it worked fine from my desktop. The same code moved to a server in the DMZ at work didn’t work and threw a java.net.SocketException
, saying java.net.SocketException: Connection reset
“. The FTPClient class, as a subclass of the SocketClient, contains a method isConnected()
, which, when invoked, returned true. So I could login, change the working directory and disconnect with no errors thrown, but as soon as I tried to send a file I got an SocketException. The simple solution was to change the mode from Active to Passive using the enterLocalPassiveMode()
method, which would have been obvious if I had known a bit more about the FTP protocol. In short, active mode FTP means that your client connects to the FTP server on the command port and then the FTP attempts to make a connection to your client for the data port, which isn’t going to work in a completely locked down environment. Changing to passive mode means that the client connects to the server for both command and data port transmission.
Handy info! I was just having problems with the commons.net.ftp stuff, and Google brought me here. Which didn’t really answer my question, but proved interesting reading anyway.
Thanks!
Saved me heaps of trouble. Thanks.
Thanks a lot. It’s really solve my question!
Good, but… I’m still getting ‘connection reset’, even entering local passive mode!
Saved me. Thanks.
I have finally understanded the Active/Passive concept
Thank you man..you saved me a lot of time and even more troubles
Just like Daniel, although I do invoke enterLocalPassiveMode() in my code, I still get this SocketException: Connection reset when listing files, although the program works fine outside of our production locked-down environment.
Interestingly, I am able to list files using standard ftp cli client on production, so network is fine and I’m not sure what’s happening with the commons.net lib…
Any idea?
Nice! This is some good stuff to know.
Does anyone have any information on why the retrieveFile() hangs forever? And it’s behaviour is truely odd, sometimes it runs it this problem in an hour and sometimes in a day or two. Everyone’s help is appreciated.
A connection reset can still happen if your: 1) Client is blocking outbound [very rare] 2) The server (strangely) is blocking those incoming ports.
Thanks for the info, I was getting a socket timeout on a client.retrieveFile() call only in production until I added
client.enterLocalPassiveMode();
work fine now.
Thanks!!!!! helps a lot…