Skip to content

Commit 8e6ce5e

Browse files
committed
[#2514] Flush out/err PrintWriters after CommandLine.execute
print() does not trigger autoFlush on PrintWriter. Flush the root and parsed command writers in a finally block so buffered output is not lost when the JVM exits immediately after execute().
1 parent 10509c0 commit 8e6ce5e

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

src/main/java/picocli/CommandLine.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,25 @@ public int execute(String... args) {
21872187
}
21882188
} catch (Exception ex) {
21892189
return handleUnhandled(ex, this, getCommandSpec().exitCodeOnExecutionException());
2190+
} finally {
2191+
// #2514 print() does not auto-flush; ensure out/err buffers are flushed after execute
2192+
flush(this);
2193+
if (parseResult[0] != null) {
2194+
for (CommandLine parsed : parseResult[0].asCommandLineList()) {
2195+
flush(parsed);
2196+
}
2197+
}
2198+
}
2199+
}
2200+
private static void flush(CommandLine cmd) {
2201+
if (cmd == null) {
2202+
return;
2203+
}
2204+
if (cmd.out != null) {
2205+
cmd.out.flush();
2206+
}
2207+
if (cmd.err != null) {
2208+
cmd.err.flush();
21902209
}
21912210
}
21922211
private static int handleUnhandled(Exception ex, CommandLine cmd, int defaultExitCode) {

src/test/java/picocli/ExecuteTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,5 +1626,46 @@ public int handleParseException(ParameterException ex, String[] args) throws Exc
16261626
}
16271627
assertEquals(expected, lines);
16281628
}
1629+
1630+
@Command(name = "demo")
1631+
static class Issue2514Command implements Callable<Integer> {
1632+
@Spec CommandSpec spec;
1633+
private final boolean writeErr;
1634+
1635+
Issue2514Command(boolean writeErr) {
1636+
this.writeErr = writeErr;
1637+
}
1638+
1639+
public Integer call() {
1640+
if (writeErr) {
1641+
spec.commandLine().getErr().print("err-hello");
1642+
} else {
1643+
spec.commandLine().getOut().print("hello");
1644+
}
1645+
return 0;
1646+
}
1647+
}
1648+
1649+
@Test
1650+
public void testExecuteFlushesOutAfterPrintWithoutNewline() {
1651+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
1652+
PrintWriter out = CommandLine.newPrintWriter(baos, getStdoutEncoding());
1653+
1654+
int exit = new CommandLine(new Issue2514Command(false)).setOut(out).execute();
1655+
1656+
assertEquals(ExitCode.OK, exit);
1657+
assertEquals("hello", baos.toString());
1658+
}
1659+
1660+
@Test
1661+
public void testExecuteFlushesErrAfterPrintWithoutNewline() {
1662+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
1663+
PrintWriter err = CommandLine.newPrintWriter(baos, getStdoutEncoding());
1664+
1665+
int exit = new CommandLine(new Issue2514Command(true)).setErr(err).execute();
1666+
1667+
assertEquals(ExitCode.OK, exit);
1668+
assertEquals("err-hello", baos.toString());
1669+
}
16291670
}
16301671

0 commit comments

Comments
 (0)