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.