SSHJ навсегда зависает при соединении () - PullRequest
4 голосов
/ 24 февраля 2012

Я выполняю некоторые команды, используя 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, сразу же возвращается.

Есть идеи, почему и как это преодолеть?

EDIT: то же самое происходит, когда я не присоединяюсь (), но читаю команду (с помощью commons-io):

IOUtils.toString(commandObject.getInputStream()))

Ответы [ 2 ]

2 голосов
/ 21 августа 2012

Предположительно, Java-приложение, которое вы запускаете, является демоном? (или, по крайней мере, долго ждет, прежде чем выйти)

Может быть, лучше иметь специальный скрипт на вашей целевой машине, который контролирует инициализацию / завершение работы демона, а не полагается на SSH-клиентов для отправки правильной последовательности команд. Таким образом, скрипт инкапсулирует все, что нужно для правильного запуска и остановки вашего демона и других приложений, которым необходимо управлять им, просто вызовите этот скрипт, чтобы запустить и остановить его, не зная подробностей о том, куда войти, команда java, необходимая для его запуска как справиться с процессом и т. д.

Вы можете либо свернуть свой собственный скрипт в стиле init, либо использовать для этого Оболочку службы Java Tanuki (или аналогичную).

1 голос
/ 16 марта 2016

У меня возникла та же проблема.

Моя личная рекомендация заключается в том, что всякий раз, когда вы используете 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) {}

Надеюсь, это может быть полезно для любого, имеющего подобную проблему.

...