Reputation: 3634
I have the following integration test code where I start various services before the test can run:
@BeforeClass
public static void setup() throws Exception {
// Set some vars like javaBin location
ProcessBuilder builder = new ProcessBuilder(javaBin, "-jar", "app.jar");
Process process = launchProcess(builder);
}
private static Process launchProcess(ProcessBuilder builder) throws IOException {
AtomicReference<Process> process = new AtomicReference<>();
new Thread(() -> {
try {
process.set(builder.start());
BufferedReader processStd = new BufferedReader(new InputStreamReader(process.get().getInputStream());
BufferedReader processErr = new BufferedReader(new InputStreamReader(process.get().getErrorStream()));
// To prevent deadlocks due to limited buffer size
String s = "";
while(processStd .readLine() != null) {}
while((s = processErr .readLine()) != null) {
System.err.println(s);
}
}
catch (IOException e) {
e.printStackTrace();
}
}).start();
return process.get();
}
The process starts OK, but I process.get()
always returns null
. What am I doing wrong? How can I get a reference to the started process using the above approach? If I set the process in the setup()
function itself, i.e. process = builder.start()
, then it works correctly. However, it also leads to a lot of repetition as I need to start numerous separate services in separate JVMs.
Upvotes: 0
Views: 59
Reputation: 439
The problem is most likely that the thread hasn't actually started by the time you return with process.get()
at the end of launchProcess
.
You will need to wait for the thread to actually start and execute the call to process.set(builder.start())
before returning from your method.
This could be done with something as simple as a CountDownLatch
.
private static Process launchProcess(ProcessBuilder builder) throws IOException {
final CountDownLatch latch = new CountDownLatch(1);
// ...
new Thread(() -> {
try {
process.set(builder.start());
latch.countDown();
//...
} catch (IOException e) {
//...
}
}).start();
latch.await();
return process.get();
}
Upvotes: 2