I have a Python server that I start with a Java ProcessBuilder thread. The Java program should wait until the server is ready before proceeding. When the server is ready, it outputs a "Server-ready" message, which I assume is picked up by the Process object's InputStream.
START_SERVER_COMMAND = TAGGERFLOW_HOME + "server.py";
server = new ProcessBuilder().inheritIO().command("python", START_SERVER_COMMAND, "" + portNum,
config.featOrderName(), config.childOrderName(), "" + maxBeta).start();
System.out.println("Hypertagger server started");
LOGGER.log(Level.INFO, "Hypertagger server started");
String line = null;
while(line == null) {
line = new BufferedReader(new InputStreamReader(server.getInputStream())).readLine();
if(line == null)
Thread.sleep(5000);
}
System.out.println("Exit loop");
However, line
is always null, and so Java never exits the loop. That most likely indicates that my assumption about the InputStream picking up the "Server-ready" message is wrong, but I don't know why that would be the case.
I'm looking for either a way to pick up the "Server-ready" message or a better way to detect when the server is ready. Any help would be appreciated.
EDIT
Before this, I tried initializing the BufferedReader before the loop. It had the same behavior.
TL;DR: If you want your Java program to capture the output, don't redirect the output elsewhere, i.e. don't call inheritIO()
, though you might want to call redirectErrorStream(true)
.
What do you think inheritIO()
does?
Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
This is a convenience method. An invocation of the form
pb.inheritIO()
behaves in exactly the same way as the invocation
pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT)
When I/O is redirected, what do you think getInputStream()
does?
Returns the input stream connected to the normal output of the subprocess. The stream obtains data piped from the standard output of the process represented by this
Process
object.If the standard output of the subprocess has been redirected using
ProcessBuilder.redirectOutput
then this method will return a null input stream.
Should be obvious, but what is a null input stream?
a destination for standard output and standard error. By default, the subprocess writes standard output and standard error to pipes. Java code can access these pipes via the input streams returned by
Process.getInputStream()
andProcess.getErrorStream()
. However, standard output and standard error may be redirected to other destinations usingredirectOutput
andredirectError
. In this case,Process.getInputStream()
and/orProcess.getErrorStream()
will return a null input stream, for which:
- the
read
methods always return-1
- the
available
method always returns0
- the
close
method does nothing