2012-02-23 3 views
4

я выполнить некоторые команды с помощью SSHJ, я делаю это с помощью этого метода:SSHJ висит вечно на Join()

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(); 

Конечно, начинается процесс. Также сразу же возвращается одна и та же строка из оболочки.

Любая идея, почему и как ее преодолеть?

EDIT: то же самое происходит, когда я не присоединиться(), но читать SYSOUT команды (с Викисклада гипергликемии):

IOUtils.toString(commandObject.getInputStream())) 
+0

Одной из идей было бы перенаправить stdin и stderr, поэтому размещение '2> & 1' до последнего амперсанда может помочь. Хотя, у меня есть аналогичная проблема с другой командой, поэтому она, вероятно, не решит полностью ее. – bstempi

+0

Исправление к моему комментарию: это бесполезно - nohup перенаправит вас, если вы не укажете иначе. Я заметил, что в этой библиотеке есть некоторые проблемы с потоками; возможно, вы столкнулись с одним? – bstempi

+0

@ilfrin, Основной поток блокирует, потому что вы вызываете 'commandObject.join()' без таймаута. Это блокирует текущий поток для ожидания уведомления. Если вызываемая программа зависает, также висит основной поток. – Boyan

ответ

2

Предположительно Java приложение, которое вы бежите это демон ? (или, по крайней мере, он долго ждал до выхода)

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

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

0

У меня была такая же проблема.

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^