|
29 | 29 | import java.util.List; |
30 | 30 | import java.util.Map; |
31 | 31 | import java.util.Optional; |
| 32 | +import java.util.concurrent.CompletableFuture; |
| 33 | +import java.util.concurrent.ExecutionException; |
32 | 34 | import java.util.concurrent.TimeUnit; |
33 | 35 | import java.util.logging.Logger; |
34 | 36 | import java.util.stream.Collectors; |
@@ -210,34 +212,45 @@ public static ProcessExecOutput runProcessGetFullOutput( |
210 | 212 | } |
211 | 213 | } |
212 | 214 |
|
213 | | - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
214 | | - StringBuilder output = new StringBuilder(); |
215 | | - String line; |
216 | | - while ((line = reader.readLine()) != null) { |
217 | | - output.append(line); |
218 | | - if (!line.endsWith(System.lineSeparator())) { |
219 | | - output.append("\n"); |
220 | | - } |
221 | | - } |
| 215 | + CompletableFuture<String> stdoutFuture = |
| 216 | + CompletableFuture.supplyAsync(() -> drainStream(process.getInputStream())); |
| 217 | + CompletableFuture<String> stderrFuture = |
| 218 | + CompletableFuture.supplyAsync(() -> drainStream(process.getErrorStream())); |
222 | 219 |
|
223 | | - reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); |
224 | | - StringBuilder error = new StringBuilder(); |
225 | | - while ((line = reader.readLine()) != null) { |
226 | | - error.append(line); |
227 | | - if (!line.endsWith(System.lineSeparator())) { |
228 | | - error.append("\n"); |
229 | | - } |
| 220 | + boolean finished = process.waitFor(30L, TimeUnit.SECONDS); |
| 221 | + if (!finished) { |
| 222 | + process.destroyForcibly(); |
| 223 | + throw new RuntimeException( |
| 224 | + String.format("Command '%s' timed out after 30 seconds", join(" ", cmdList))); |
230 | 225 | } |
231 | 226 |
|
232 | | - process.waitFor(30L, TimeUnit.SECONDS); |
233 | | - |
234 | | - return new ProcessExecOutput(output.toString(), error.toString(), process.exitValue()); |
235 | | - } catch (IOException | InterruptedException e) { |
| 227 | + return new ProcessExecOutput(stdoutFuture.get(), stderrFuture.get(), process.exitValue()); |
| 228 | + } catch (InterruptedException e) { |
| 229 | + Thread.currentThread().interrupt(); |
| 230 | + throw new RuntimeException( |
| 231 | + String.format("Command '%s' was interrupted", join(" ", cmdList)), e); |
| 232 | + } catch (ExecutionException e) { |
| 233 | + throw new RuntimeException( |
| 234 | + String.format("Failed reading output of command '%s'", join(" ", cmdList)), e); |
| 235 | + } catch (IOException e) { |
236 | 236 | throw new RuntimeException( |
237 | 237 | String.format("Failed to execute command '%s' ", join(" ", cmdList)), e); |
238 | 238 | } |
239 | 239 | } |
240 | 240 |
|
| 241 | + private static String drainStream(java.io.InputStream inputStream) { |
| 242 | + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { |
| 243 | + StringBuilder sb = new StringBuilder(); |
| 244 | + String line; |
| 245 | + while ((line = reader.readLine()) != null) { |
| 246 | + sb.append(line).append("\n"); |
| 247 | + } |
| 248 | + return sb.toString(); |
| 249 | + } catch (IOException e) { |
| 250 | + throw new RuntimeException("Failed to read process stream", e); |
| 251 | + } |
| 252 | + } |
| 253 | + |
241 | 254 | public static class ProcessExecOutput { |
242 | 255 | private final String output; |
243 | 256 | private final String error; |
|
0 commit comments