Pankraz76 commented on issue #13735: URL: https://github.com/apache/maven/issues/13735#issuecomment-6491155109
Thanks for the excellent analysis and the strace numbers. They made this straightforward to pin down. Fix: #13747 (targets `maven-3.10.x`). **Root cause** (slightly broader than suspected): when stdout is not a terminal, JLine falls back to a dumb system terminal writing to a raw `FileOutputStream(FileDescriptor.out)`. That stream is wrapped in `DumbTerminalProvider$NonCloseableOutputStream`, a `FilterOutputStream` without a bulk `write(byte[], int, int)`, and `AnsiOutputStream` on top only implements `write(int)` as well. So buffering above JLine's stream wouldn't help; the buffer has to sit directly on the file descriptor. Real TTYs are unaffected because `PosixSysTerminal` already buffers. **Fix:** `MessageUtils.systemInstall()` replaces JLine's dumb system terminal with an equivalent `DumbTerminal` that writes to the same fd through a synchronized 8 KiB `BufferedOutputStream`, as Jansi 2.x did in 3.9.x. Output is still flushed per line and on exit, and ANSI stripping is unchanged. **Measured** (`strace` on fd 1, stdout piped): | | before | after | |---|---|---| | `mvn -B -X help:evaluate` | 56,358 writes (56,339 single-byte) | 1,163 writes | | one 15 KiB line | 15,509 writes | 10 writes | Whether you hit this depends on timing: `simplelogger.properties` sets `cacheOutputStream=true`, so the logger keeps whichever `System.out` exists when it starts, and that races the asynchronous terminal install. That also explains why some runs look fine. `-Dorg.slf4j.simpleLogger.cacheOutputStream=false` reproduces it deterministically. Until a release ships the fix, `-l /dev/stdout` remains the workaround, as you found. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
