我继承了一个基于Java的项目,该项目包括一个cron作业,用于通过SFTP将文件上传到第三方服务器。这是相关的代码。
String filePath = IUtil.getInstance().getProperties("cheetah_sftp_filepath");
try{
SshClient ssh = new SshClient();
ssh.connect(host, port);
//Authenticate
PasswordAuthenticationClient passwordAuthenticationClient = new PasswordAuthenticationClient();
passwordAuthenticationClient.setUsername(userName);
passwordAuthenticationClient.setPassword(password);
int result = ssh.authenticate(passwordAuthenticationClient);
if(result != AuthenticationProtocolState.COMPLETE){
throw new Exception("Login to " + host + ":" + port + " " + userName + "/" + password + " failed");
}
//Open the SFTP channel
SftpClient client = ssh.openSftpClient();
client.cd("autoproc");
client.put(filePath);
//disconnect
client.quit();
ssh.disconnect();
} catch(Exception e) {
String message = "Failed during sftp: " + e.getMessage();
addJobMessage(message, JobMessageType.JOB_MESSAGE_TYPE_ERROR);
e.printStackTrace();
return false;
}
非常简单,但它不起作用。当client.put()
执行时,它会因“java.io.IOException:No such file”而失败。这是堆栈跟踪。
java.io.IOException: No such file
at com.sshtools.j2ssh.sftp.SftpSubsystemClient.getOKRequestStatus(Unknown Source)
at com.sshtools.j2ssh.sftp.SftpSubsystemClient.setAttributes(Unknown Source)
at com.sshtools.j2ssh.sftp.SftpSubsystemClient.changePermissions(Unknown Source)
at com.sshtools.j2ssh.SftpClient.chmod(Unknown Source)
at com.sshtools.j2ssh.SftpClient.put(Unknown Source)
at com.sshtools.j2ssh.SftpClient.put(Unknown Source)
at com.sshtools.j2ssh.SftpClient.put(Unknown Source)
at com.sshtools.j2ssh.SftpClient.put(Unknown Source)
at com.dez.store.scripts.SendEmailShellCommand.sftpToCheetah(SendEmailToCheetahShellCommand.java:99)
at com.dez.store.scripts.SendEmailShellCommand.execute(SendEmailToCheetahShellCommand.java:34)
at com.fry.ocp.common.ShellCommandExecutor.main(ShellCommandExecutor.java:90)
filePath
是文件的绝对路径。是的,我检查了显而易见的:路径是正确的,文件存在。文件权限为664,因此在任何情况下读取都不应失败,但该进程以root身份运行以进行引导。
我已经尝试了我能想到的一切。
lcd()
到目录,然后我到达lpwd()
。这似乎很好,但仍然失败,所以一个长路径名称似乎不是问题。j2ssh.sftp.SftpFile
实例并查看它是否可以访问该文件,并确保“无此文件”错误与远程主机无关。当我执行SftpFile.canRead()
时,我得到一个空指针异常,所以我认为这是一个本地问题。多年来我没有接触过Java。说我生锈将是一个严重的轻描淡写。然而,我们最后一个“Java家伙”刚刚退出,我是我店里唯一一个触及Java 永远的人,所以我是新的“Java家伙”。
我错过了一些简单的东西吗?还有其他想法吗?
-Sean
答案 0 :(得分:1)
从callstack和你的描述中,我希望错误引用远程文件。
chmod
必须在传输完成后才能完成,因此我假设SftpClient
认为传输已完成,并尝试更新远程文件权限。似乎它失败了,因为文件实际上并不存在。收到错误后,使用SftpClient.ls()
检查文件是否存在。有可能你有一些远程端进程在上传完成时将文件带走。
作为一种变通方法,您还可以尝试阻止SftpClient
尝试在上传完成后修改权限。我不知道J2SSH。快速浏览一下,我还没有找到任何API。也许是SftpClient.umask()
。
您可以尝试切换到JSch。上传后似乎没有隐式chmod
。
还值得检查远程服务器日志。