Ich verwende den ProcessBuilder von Java, um einen Unterprozess zu starten, der ein weiteres Java-Programm ist, das in einer separaten JVM laufen muss.
Ich starte zwei Threads, um von den Streams stdout und stderr des Prozesses zu lesen, so dass es nicht zu einem Hänger kommt, wenn die Stream-Puffer voll sind. Der Aufruf von Process.waitFor kehrt zurück, aber die Streams werden nicht beendet.
Der von mir verwendete Code sieht in etwa so aus (Befehl ist eine Liste von Zeichenketten):
ProcessBuilder pb = new ProcessBuilder(command);
final Process p = pb.start();
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
Thread outputThread = new Thread() {
@Override
public void run() {
try {
IOUtils.copy(p.getInputStream(), outStream);
} catch (IOException e) {
e.printStackTrace();
}
};
};
outputThread.start();
Thread errorThread = new Thread() {
@Override
public void run() {
try {
IOUtils.copy(p.getErrorStream(), errStream);
} catch (IOException e) {
e.printStackTrace();
}
};
};
errorThread.start();
int returncode = p.waitFor();
outputThread.join();
errorThread.join();
Wenn ich etwas anderes ausführe, z. B. "java -version" oder "dir" oder so, funktioniert der Code einwandfrei. Ich habe Zugriff auf den Java-Code, den ich auszuführen versuche, aber ich habe noch nie gehört, dass man close() auf System.out aufrufen sollte.