Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;远程确认失败:scp:目标不明确“;上载文件时使用;scp“;当它在Linux和Mac上工作时_Java_Windows_Scp_Jsch - Fatal编程技术网

Java &引用;远程确认失败:scp:目标不明确“;上载文件时使用;scp“;当它在Linux和Mac上工作时

Java &引用;远程确认失败:scp:目标不明确“;上载文件时使用;scp“;当它在Linux和Mac上工作时,java,windows,scp,jsch,Java,Windows,Scp,Jsch,我正在尝试运行一个测试用例,它基本上将一个文件从我的机器复制到docker中运行的模拟服务器。同样的测试在Mac和Ubuntu上也能正常工作。但在Windows上,它将失败,出现以下错误:- 在远程SSH服务器上执行命令时出现异常 java.lang.RuntimeException:在远程SSH服务器上执行命令时发生异常 位于com.org.implementation.RemoteCommandWrapper.runSshCommandWithTimeout(RemoteCommandWra

我正在尝试运行一个测试用例,它基本上将一个文件从我的机器复制到docker中运行的模拟服务器。同样的测试在Mac和Ubuntu上也能正常工作。但在Windows上,它将失败,出现以下错误:-

在远程SSH服务器上执行命令时出现异常 java.lang.RuntimeException:在远程SSH服务器上执行命令时发生异常 位于com.org.implementation.RemoteCommandWrapper.runSshCommandWithTimeout(RemoteCommandWrapper.java:53) 位于com.org.implementation.RemoteCommandWrapper.copyLocalToRemote(RemoteCommandWrapper.java:121) ... 原因:java.util.concurrent.ExecutionException:java.lang.RuntimeException:远程确认失败:scp:目标不明确 位于java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395) 位于java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2022) 位于com.org.implementation.cboserver.RemoteCommandWrapper.runSshCommandWithTimeout(RemoteCommandWrapper.java:49) ... 92多 原因:java.lang.RuntimeException:远程确认失败:scp:目标不明确 位于com.org.implementation.RemoteCommandWrapper.checkAck(RemoteCommandWrapper.java:174) 位于com.org.implementation.RemoteCommandWrapper.WaitForFileCopy(RemoteCommandWrapper.java:136) 位于com.org.implementation.RemoteCommandWrapper.lambda$copyLocalToRemote$1(RemoteCommandWrapper.java:124) 在com.org.implementation.RemoteCommandWrapper.tryToExecuteCommand(RemoteCommandWrapper.java:68)上 在com.org.implementation.RemoteCommandWrapper.lambda$runSshCommandWithTimeout$0(RemoteCommandWrapper.java:45) ... RemoteCommand.java:-

public void copyLocalToRemote(Session session, Path localPath, Path remotePath, String fileName) {
    log.info("localPath: {}",localPath); //localPath:C:\Users\myuser\project1\src\test\resources\5f9cce18-362e-4973-a26b-730131841d7b
    log.info("remotePath: {}",remotePath); // remotePath:\
    log.info("fileName: {}",fileName);// fileName: CustomFile.zip
    String copyCommand = createCopyCommand(remotePath);
    runSshCommandWithTimeout(session,
            copyCommand,
            (channel, in, out) -> {
                waitForFileCopied(channel, in, out, localPath, fileName);
                return null;
            });
}

private String createCopyCommand(Path remotePath) {
    return String.format("scp -p -t %s\n", remotePath);
}

private void waitForFileCopied(Channel channel, InputStream in, OutputStream out, Path localPath, String fileName) {
    Path from = localPath.resolve(fileName);
    try (FileInputStream fis = new FileInputStream(from.toString())) {
        checkAck(in);
        setFileAccess(from, out, in);
        fis.transferTo(out);

        // send '\0'
        out.write(new byte[]{0}, 0, 1);
        out.flush();
        checkAck(in);
    } catch (IOException e) {
        throw new RuntimeException("Error copying custom file", e);
    }
}

@SneakyThrows
private void checkAck(InputStream in){
    int b = in.read();
    if (b == 0) return;

    if (b < 0) throw new RuntimeException("Remote Acknowledge failed: " + Integer.valueOf(b));

    StringBuilder sb = new StringBuilder();
    int c;
    do {
        c = in.read();
        sb.append((char) c);
    }
    while (c != '\n');
    throw new RuntimeException("Remote Acknowledge failed: " + sb.toString());
}

<T> T runSshCommandWithTimeout(final Session session, String command, RemoteResultFactory<T> resultFactory) {
    CompletableFuture<T> future = CompletableFuture.supplyAsync(
            () -> tryToExecuteCommand(session, command, resultFactory)
    );

    try {
        return future.get(timeoutMs, TimeUnit.MILLISECONDS);
    } catch (TimeoutException e) {
        throw new RemoteTimeoutException(String.format("Timeout while executing command on remote SSH server: %d ms", timeoutMs));
    } catch (Exception e) {
        throw new RuntimeException("Exception while executing command on remote SSH server", e);
    }
}

private <T> T tryToExecuteCommand(Session session, String command, RemoteResultFactory<T> resultFactory) {
    Channel channel = null;
    try {
        channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        // TODO handle extInputStream (error stream)
        try (InputStream in = channel.getInputStream();
             OutputStream out = channel.getOutputStream()) {

            channel.connect();
            return resultFactory.getResult(channel, in, out);
        }
    } catch (JSchException | IOException e) {
        throw new RuntimeException("Exception while executing command on remote SSH server", e);
    } finally {
        if (channel != null) {
            channel.disconnect();
        }
        session.disconnect();
    }
}
public void copyLocalToRemote(会话会话、路径localPath、路径remotePath、字符串文件名){
log.info(“localPath:{}”,localPath);//localPath:C:\Users\myuser\project1\src\test\resources\5f9cce18-362e-4973-a26b-730131841d7b
log.info(“remotePath:{}”,remotePath);//remotePath:\
log.info(“文件名:{}”,文件名);//文件名:CustomFile.zip
字符串copyCommand=createCopyCommand(远程路径);
runSshCommandWithTimeout(会话,
copyCommand,
(频道、输入、输出)->{
WaitForFileCopy(通道、输入、输出、本地路径、文件名);
返回null;
});
}
私有字符串createCopyCommand(路径远程路径){
返回String.format(“scp-p-t%s\n”,remotePath);
}
私有void WaitForFileCopy(通道通道、输入流输入、输出流输出、路径localPath、字符串文件名){
Path from=localPath.resolve(文件名);
try(FileInputStream fis=newfileinputstream(from.toString())){
签入;
setFileAccess(从、出、入);
财政司司长转拨(拨出);
//发送“\0”
写入(新字节[]{0},0,1);
out.flush();
签入;
}捕获(IOE异常){
抛出新的RuntimeException(“复制自定义文件时出错”,e);
}
}
@鬼鬼祟祟
私有void checkAck(InputStream-in){
int b=in.read();
如果(b==0)返回;
如果(b<0)抛出新的RuntimeException(“远程确认失败:+Integer.valueOf(b));
StringBuilder sb=新的StringBuilder();
INTC;
做{
c=in.read();
sb.附加((char)c);
}
而(c!='\n');
抛出新的RuntimeException(“远程确认失败:+sb.toString());
}
T runSshCommandWithTimeout(最终会话会话、字符串命令、RemoteResultFactory resultFactory){
CompletableFuture=CompletableFuture.SupplySync(
()->tryToExecuteCommand(会话、命令、结果工厂)
);
试一试{
返回future.get(timeoutMs,TimeUnit.ms);
}捕获(超时异常e){
抛出新的RemoteTimeoutException(String.format(“在远程SSH服务器上执行命令时超时:%d ms”,timeoutMs));
}捕获(例外e){
抛出新的RuntimeException(“在远程SSH服务器上执行命令时发生异常”,e);
}
}
私有T tryToExecuteCommand(会话会话、字符串命令、RemoteResultFactory resultFactory){
通道=空;
试一试{
channel=session.openChannel(“exec”);
((ChannelExec)channel).setCommand(command);
//TODO句柄流(错误流)
try(InputStream in=channel.getInputStream();
OutputStream out=channel.getOutputStream()){
channel.connect();
返回resultFactory.getResult(通道、输入、输出);
}
}捕获(JSCHEException | IOException e){
抛出新的RuntimeException(“在远程SSH服务器上执行命令时发生异常”,e);
}最后{
如果(通道!=null){
通道断开();
}
session.disconnect();
}
}
在Google上搜索此错误时,我可以理解
scp
无法识别目标目标,这也是窗口路径的问题,或者可能是因为
“/”
“\”
,因为相同的测试正在基于Linux的文件系统(以及Mac)上进行

我无法弄清确切的问题以及如何解决它

有人能提出一些建议来恢复吗


谢谢

远程路径必须是
/
,而不是
\

createCopyCommand
的参数不能是
Path
,因为在Windows上,它将
/
转换为
\