12
12
import java .util .List ;
13
13
import java .util .Map ;
14
14
import java .util .Objects ;
15
+ import java .util .concurrent .CompletableFuture ;
15
16
import java .util .stream .Collectors ;
16
17
17
18
import com .devonfw .tools .ide .cli .CliException ;
@@ -134,17 +135,21 @@ public ProcessResult run(ProcessMode processMode) {
134
135
135
136
this .processBuilder .command (args );
136
137
137
- Process process = this .processBuilder .start ();
138
+ List <String > out = new ArrayList <>();
139
+ List <String > err = new ArrayList <>();
138
140
139
- List <String > out = null ;
140
- List <String > err = null ;
141
+ Process process = this .processBuilder .start ();
141
142
142
143
if (processMode == ProcessMode .DEFAULT_CAPTURE ) {
143
- try (BufferedReader outReader = new BufferedReader (new InputStreamReader (process .getInputStream ()))) {
144
- out = outReader .lines ().collect (Collectors .toList ());
144
+ CompletableFuture <String > outFut = readInputStream (process .getInputStream ());
145
+ CompletableFuture <String > errFut = readInputStream (process .getErrorStream ());
146
+ String outString = outFut .get ();
147
+ String errString = errFut .get ();
148
+ if (!outString .isEmpty ()) {
149
+ out .add (outString );
145
150
}
146
- try ( BufferedReader errReader = new BufferedReader ( new InputStreamReader ( process . getErrorStream ()) )) {
147
- err = errReader . lines (). collect ( Collectors . toList () );
151
+ if (! errString . isEmpty ( )) {
152
+ err . add ( errString );
148
153
}
149
154
}
150
155
@@ -171,6 +176,30 @@ public ProcessResult run(ProcessMode processMode) {
171
176
}
172
177
}
173
178
179
+ /**
180
+ * Asynchronously and parallel reads {@link InputStream input stream} and stores it in {@link CompletableFuture}.
181
+ * Taken from:
182
+ * https://stackoverflow.com/questions/14165517/processbuilder-forwarding-stdout-and-stderr-of-started-processes-without-blocki/57483714#57483714
183
+ *
184
+ * @param is {@link InputStream}.
185
+ * @return {@link CompletableFuture}.
186
+ */
187
+ private static CompletableFuture <String > readInputStream (InputStream is ) {
188
+
189
+ return CompletableFuture .supplyAsync (() -> {
190
+ try (InputStreamReader isr = new InputStreamReader (is ); BufferedReader br = new BufferedReader (isr );) {
191
+ StringBuilder res = new StringBuilder ();
192
+ String inputLine ;
193
+ while ((inputLine = br .readLine ()) != null ) {
194
+ res .append (inputLine ).append (System .lineSeparator ());
195
+ }
196
+ return res .toString ();
197
+ } catch (Throwable e ) {
198
+ throw new RuntimeException ("There was a problem while executing program" , e );
199
+ }
200
+ });
201
+ }
202
+
174
203
private String createCommandMessage (String interpreter , String suffix ) {
175
204
176
205
StringBuilder sb = new StringBuilder ();
0 commit comments