Skip to content

Commit 7fcd5e1

Browse files
committed
Ensure stream gobblers are properly finished
1 parent 3a76a9c commit 7fcd5e1

2 files changed

Lines changed: 14 additions & 16 deletions

File tree

lib/src/main/java/org/sonarsource/scanner/lib/internal/JavaRunner.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@
2222
import com.google.gson.Gson;
2323
import com.google.gson.annotations.SerializedName;
2424
import java.io.BufferedReader;
25-
import java.io.BufferedWriter;
2625
import java.io.IOException;
2726
import java.io.InputStream;
2827
import java.io.InputStreamReader;
29-
import java.io.OutputStream;
3028
import java.io.OutputStreamWriter;
3129
import java.nio.charset.StandardCharsets;
3230
import java.nio.file.Path;
@@ -56,17 +54,22 @@ public void execute(List<String> args, @Nullable String input) {
5654
try {
5755
List<String> command = new ArrayList<>(args);
5856
command.add(0, javaExecutable.toString());
57+
LOG.atDebug().addArgument(() -> String.join(" ", command)).log("Executing: {}");
5958
Process process = new ProcessBuilder(command).start();
6059
if (input != null) {
61-
try (OutputStream stdin = process.getOutputStream();
62-
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin, StandardCharsets.UTF_8))) {
63-
writer.write(input);
60+
try (var stdin = process.getOutputStream(); var osw = new OutputStreamWriter(stdin, StandardCharsets.UTF_8)) {
61+
osw.write(input);
6462
}
6563
}
66-
new StreamGobbler(process.getInputStream(), this::tryParse).start();
67-
new StreamGobbler(process.getErrorStream(), stderr -> LOG.error("[stderr] {}", stderr)).start();
68-
if (process.waitFor() != 0) {
69-
throw new IllegalStateException("Error returned by the Java command execution");
64+
var stdoutConsummer = new StreamGobbler(process.getInputStream(), this::tryParse);
65+
var stdErrConsummer = new StreamGobbler(process.getErrorStream(), stderr -> LOG.error("[stderr] {}", stderr));
66+
stdErrConsummer.start();
67+
stdoutConsummer.start();
68+
var exitCode = process.waitFor();
69+
stdoutConsummer.join();
70+
stdErrConsummer.join();
71+
if (exitCode != 0) {
72+
throw new IllegalStateException("Error returned by the Java command execution: " + process.exitValue());
7073
}
7174
} catch (IOException | InterruptedException e) {
7275
Thread.currentThread().interrupt();

lib/src/test/java/org/sonarsource/scanner/lib/internal/JavaRunnerTest.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
import static org.assertj.core.api.Assertions.assertThat;
3030
import static org.assertj.core.api.Assertions.assertThatThrownBy;
31-
import static org.awaitility.Awaitility.await;
3231

3332
class JavaRunnerTest {
3433

@@ -40,14 +39,10 @@ void execute_shouldLogProcessOutput() {
4039
JavaRunner runner = new JavaRunner(Paths.get("java"), JreCacheHit.DISABLED);
4140

4241
runner.execute(List.of("--version"), "test");
43-
await().untilAsserted(() -> {
44-
assertThat(logTester.logs(Level.INFO)).isNotEmpty().allMatch(s -> s.startsWith("[stdout] "));
45-
});
42+
assertThat(logTester.logs(Level.INFO)).isNotEmpty().allMatch(s -> s.startsWith("[stdout] "));
4643

4744
runner.execute(List.of("-version"), null);
48-
await().untilAsserted(() -> {
49-
assertThat(logTester.logs(Level.ERROR)).isNotEmpty().allMatch(s -> s.startsWith("[stderr] "));
50-
});
45+
assertThat(logTester.logs(Level.ERROR)).isNotEmpty().allMatch(s -> s.startsWith("[stderr] "));
5146
}
5247

5348
@Test

0 commit comments

Comments
 (0)