sshtools.SftpClient.put失败并显示“No such file”

时间:2013-05-28 23:38:16

标签: java sftp j2ssh

我继承了一个基于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

1 个答案:

答案 0 :(得分:1)

从callstack和你的描述中,我希望错误引用远程文件。

chmod必须在传输完成后才能完成,因此我假设SftpClient认为传输已完成,并尝试更新远程文件权限。似乎它失败了,因为文件实际上并不存在。收到错误后,使用SftpClient.ls()检查文件是否存在。有可能你有一些远程端进程在上传完成时将文件带走。

作为一种变通方法,您还可以尝试阻止SftpClient尝试在上传完成后修改权限。我不知道J2SSH。快速浏览一下,我还没有找到任何API。也许是SftpClient.umask()

您可以尝试切换到JSch。上传后似乎没有隐式chmod

还值得检查远程服务器日志。