ilfrin
ilfrin

Reputation: 261

SSHJ hangs forever on join()

I execute some commands using SSHJ, I do it using this method:

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

It works well until I execute this command:

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

In this case the whole program hangs on

commandObject.join();

Of course the process it starts is started. Also the same line executed from shell returns right away.

Any idea why and how to overcome this?

EDIT: the same happens when I don't join() but read the sysout of the command (with commons-io):

IOUtils.toString(commandObject.getInputStream()))

Upvotes: 4

Views: 1393

Answers (2)

I have had the same issue.

My personal recommendation is that whenever you use join you should actually set some timeout for it to expire and don't lock the thread forever. In my case for using multiple commands I initialize a Shell instance, and, for instance would do something like this:

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) {}

Hope it may be useful for anybody having some similar problem.

Upvotes: 1

Jonny
Jonny

Reputation: 882

Presumably the java app you're running is a daemon? (or at least, it waits a long time before exiting)

It may be better to have a dedicated script on your target machine that controls the initialisation/shutdown of the daemon rather than relying on SSH clients to send the correct sequence of commands. This way, the script encapsulates all the things needed to cleanly start and stop your daemon and other apps that need to control it simply call this script to start and stop without needing to know details about where to log, the java command needed to start it, how to background the process, etc.

You can either roll your own init-style script or use Tanuki's Java Service Wrapper (or similar) for this.

Upvotes: 2

Related Questions