SSHJ永远挂起join()

时间:2012-02-23 21:39:16

标签: sshj

我使用SSHJ执行一些命令,我​​使用这种方法执行:

  private Command executeCommand(String command, SSHClient client) {
    Command commandObject = client.startSession().exec(command);
    commandObject.join();
    return commandObject;
  }

在我执行此命令之前一切正常:

cd $SOLR; nohup java -Dsolr.solr.home=./solr -DSTOP.PORT=8079 -DSTOP.KEY=stopkey -jar start.jar 2> logs/solr.log &

在这种情况下,整个程序挂起

commandObject.join();

当然,它启动的过程已经开始。从shell执行的同一行也会立即返回。

知道为什么以及如何克服这个问题?

编辑: 当我不加入()但读取命令的sysout(使用commons-io)时会发生同样的情况:

IOUtils.toString(commandObject.getInputStream()))

2 个答案:

答案 0 :(得分:2)

据推测,你正在运行的java应用程序是一个守护进程? (或者至少,它在退出前等了很长时间)

最好在目标计算机上安装一个专用脚本来控制守护程序的初始化/关闭,而不是依靠SSH客户端发送正确的命令序列。这样,脚本封装了干净地启动和停止守护进程所需的所有东西以及需要控制它的其他应用程序,只需调用此脚本即可启动和停止,而无需了解有关记录位置的详细信息,启动它所需的java命令,如何背景这个过程等。

您可以滚动自己的init样式脚本,也可以使用Tanuki's Java Service Wrapper(或类似)。

答案 1 :(得分:1)

我遇到了同样的问题。

我个人的建议是,无论何时使用join,您都应该设置一些超时,以使其过期,并且不会永久锁定该线程。在我使用多个命令的情况下,我初始化一个Shell实例,例如,它会做这样的事情:

try
{
            shell = session.startShell();
}
catch (Exception e)
{
            // failed to open
            return;
}
outputStream = shell.getOutputStream();
outputStream.write(Strings.toUTF8ByteArray("some fast command\n"));
outputStream.flush();
try {   shell.join(1, TimeUnit.SECONDS); }
catch (Exception e) {}
outputStream.write(Strings.toUTF8ByteArray("some complex command\n"));
outputStream.flush();
try {   shell.join(30, TimeUnit.SECONDS); }
catch (Exception e) {}

希望对任何遇到类似问题的人有用。