Frank-en-stein opened a new issue, #13735: URL: https://github.com/apache/maven/issues/13735
### Affected version 3.10.0 (JLine 3.30.17 / jansi-core 3.30.17). Not affected: 3.9.16 and earlier. ### Bug description ## What happens When stdout is a pipe or a file, Maven 3.10.0 issues one write(2) syscall per byte of console output. Maven 3.9.x wrote the same output in 8 KiB chunks. This matters in CI. Tools that read the pipe (buildkit, Earthly, Jenkins, Docker) receive thousands of tiny chunks per line. In our case a 15 KB surefire log line became thousands of log fragments, the CI log pipeline saturated, and the forked test JVM blocked on stdout. A 4 minute `mvn test` job no longer finished within 45 minutes. ## Impact We run `mvn --batch-mode --quiet test` under Earthly/buildkit in the `maven:3.10.0-amazoncorretto-21-alpine` image. The tests log JSON lines, some with 15 KB stack traces. - Job time went from 4 minutes on 3.9.9 to cancelled at 45 minutes on 3.10.0, on every run that rebuilt the test layer. Four branches were blocked in one afternoon. - Output reached the CI runner 30 minutes late, in 3 to 4 byte fragments, at 20 to 40 seconds per 15 KB line. The job log grew to 2.5 GB. - Once the pipes filled, the test JVM blocked inside its logging appender and looked hung. No Maven option restored the old behaviour. We have pinned our shared build image to 3.9.16 and cannot move to the 3.10 line until this is fixed. ## Cause `MessageUtils.systemInstall()` builds a dumb terminal and calls `AnsiConsole.systemInstall()`. That wraps `terminal.output()`, an unbuffered `FileOutputStream`, in `org.jline.jansi.io.AnsiOutputStream`. `AnsiOutputStream` extends `FilterOutputStream` and only overrides `write(int)`, so `write(byte[], int, int)` falls back to one `write(int)` per byte, and each one reaches the kernel. Jansi 2.x (used by 3.9.x) wrapped the descriptor in `FastBufferedOutputStream` first, so the bytes were coalesced. ## Reproduce 1. Any project with maven-surefire-plugin 3.6.1 and a JUnit test that prints a few 15 KB lines to System.out. 2. `strace -f -e trace=write -o trace.txt mvn -B -q test | cat > /dev/null` 3. Count writes to fd 1 in trace.txt. Results (same project, same JDK 21): | Maven | writes to stdout | single-byte writes | | ------ | ---------------: | -----------------: | | 3.9.16 | 30 | 6 | | 3.10.0 | 88,524 | 88,506 | `-Dstyle.color=never`, `-Djansi.mode=strip`, `-Djansi.mode=force`, `-Djansi.providers=none` and `-Dorg.jline.terminal.dumb=true` make no difference. Only `-l /dev/stdout` avoids it, because that replaces System.out with a plain PrintStream. ## Expected Console output should reach the kernel in buffered chunks regardless of whether stdout is a terminal. Either `AnsiOutputStream` should implement `write(byte[], int, int)`, or Maven should wrap the dumb terminal's output in a `BufferedOutputStream` before installing it (and flush on each log event). -- 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]
