I am using org.apache.commons.net.ftp.FTPSClient to upload file to FTPS server (over TLS/SSL).
Note the FTP server lies on Windows server, and the certificate is a self-signed one, which can be connected and have files uploaded successfully via FileZilla after I accepted the warning that the certificate is not valid.
However the java code handling the same stuff doesn't work. I have checked the connect step and loggin step separately in code, and found the error happened after connect step (ftps.connect(server,port)) - the log "Connected to server:port" has been printed in console. I am confused that getRemoteAddress should be handled during connect step, which has already completed.
String ftpsServer = "host";
int ftpsPort = 21;
String ftpsUser = "domain\username";
String ftpsPass = "password";
try{
FTPSClient ftpClient = new FTPSClient();
ftpClient.connect(ftpsServer,ftpsPort);
// check FTP connection
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)){
ftpClient.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
} else {
System.out.println("Connected to " + ftpsServer + ":" + ftpsPort + ".");
}
// check FTP login
if (ftpClient.login(ftpsUser, ftpsPass)){
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
System.out.println("Logged into FTP server successfully");
} else {
System.out.println("Failed log into FTP server");
ftpClient.logout();
ftpClient.disconnect();
}
File localFile = new File("C:/test/history.txt");
InputStream inputStream = new FileInputStream(localFile);
boolean uploaded = ftpClient.storeFile("/wwwroot/preview/history.txt", inputStream);
System.out.println("uploaded successful? " + uploaded);
inputStream.close();
ftpClient.logout();
ftpClient.disconnect();
}catch(Exception e){
LOG.error("Exception when merging Reminderlist is: ", e);
}
The full log printed in console is :
Connected to 10.20.254.xx:21.
Failed log into FTP server
ERROR 2017-10-13 15:27:15,322 [main]
com.redwood.contentmanagement.UnzipFiles: Exception when merging
Reminderlist is:
java.lang.NullPointerException
at
org.apache.commons.net.SocketClient.getRemoteAddress(SocketClient.java:553) ~[commons-net-2.2.jar:2.2]
at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:509) ~[commons-net-2.2.jar:2.2]
at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:425) ~[commons-net-2.2.jar:2.2]
at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1548) ~[commons-net-2.2.jar:2.2]
at com.redwood.contentmanagement.TransferOverFTPS.myTransform(TransferOverFTPS.java:55) ~[classes/:?]
at com.redwood.contentmanagement.TransferOverFTPS.main(TransferOverFTPS.java:110) ~[classes/:?]
Thanks a lot for @devpuh's reply, I have logged in successfully after changing \ to / in username, but still failed uploading the file, and there was no detailed information where failed, below is the full log in console:
Connected to 10.20.254.10:21.
Logged into FTP server successfully
uploaded successful? false
For the original question
Your login credentials are incorrect, but you are still trying to upload the file.
You must handle the incorrect login proper. For example:
// check FTP login
if (ftpClient.login(ftpsUser, ftpsPass)){
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
System.out.println("Logged into FTP server successfully");
} else {
System.out.println("Failed log into FTP server");
ftpClient.logout();
ftpClient.disconnect();
return;
}
For the edited question
To find out why the upload doesn't work you can get last reply from the Server with getReplyString()
. For example:
boolean uploaded = ftpClient.storeFile("/wwwroot/preview/history.txt", inputStream);
if(!uploaded) {
System.err.println("Can't upload File! Reply from Server: " + ftpClient.getReplyString());
} else {
System.out.println("Upload successful");
}
PS: the FTPClient rarely shows an error or warning message, therefore it's better to add a PrintCommandListener
to debug.
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));