JDK-8319545 : System.console().readLine() botches lines
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 22
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2023-11-06
  • Updated: 2024-03-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
The standard input in Java can be accessed, typically, though System.in or, if System.console() returns non-null, through that returned java.io.Console object.

In JDK 22, System.console() returns an object in all cases where it previously returned one, and in some other cases where it previously returned null. For that reason, it's important that reading from System.console() is consistent with reading from System.in.

Now, java.io.Console provides two ways of reading: readLine() and reader(). readLine() returns lines, whereas reader() returns java.io.Reader, which can then be used to read lines. For example, it can be wrapped into java.io.BufferedReader, which provides readLine().

The way BufferedReader slices a stream of characters into a stream of lines is OS-agnostic and standard across many Java APIs, such as java.io, java.lang.String, java.nio.file.Files.

Wrapped into BufferedReader, System.console().reader() seems to be consistent with System.in. However, System.console.readLine() is not: it slices lines differently. Thus, System.console().readLine() behaves in a non-intuitive and unexpected way. It should be fixed, specified, or both.
Comments
The PR got merged into JLine 3.25.0, thus incorporating 3.25.1 into the JDK should fix this issue
06-03-2024

Instead of internally handling line breaks from JLine uniformly, it may be possible to make use of https://github.com/jline/jline3/pull/900 which aims to do it inside JLine.
07-11-2023

Maybe surprisingly, on Windows 10 (22H2), the behaviour is the same. However, the encoding suggested by stdout.encoding (I suppose, it is the one to use not only for STDOUT but also for STDIN) is different from that of Console.charset(): openjdk-22-ea+21_windows-x64_bin\jdk-22\bin\java.exe ReadInput.java system.console.readline < input.txt lines=2, encoding=windows-1252 0 abcdef 61:62:63:64:65:66 1 ghi 67:68:69 openjdk-22-ea+21_windows-x64_bin\jdk-22\bin\java.exe ReadInput.java system.console.reader < input.txt lines=4, encoding=windows-1252 0 abc 61:62:63 1 def 64:65:66 2 ghi 67:68:69 3 jkl 6A:6B:6C openjdk-22-ea+21_windows-x64_bin\jdk-22\bin\java.exe ReadInput.java system.in < input.txt lines=4, encoding=IBM850 0 abc 61:62:63 1 def 64:65:66 2 ghi 67:68:69 3 jkl 6A:6B:6C Note: IBM850.
06-11-2023

This seems to be caused by the underlying implementation of JLine in dealing with line breaks. Implementing `readLine()` uniformly across platforms in `JdkConsoleImpl` would solve the issue.
06-11-2023

It might be related, or is separate and a bug: hexdump -C input1.txt 00000000 c2 ae 0a e0 a0 81 0d |.......| 00000007 % ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.console.readline < input1.txt lines=1, encoding=UTF-8 0 ® C2:AE % ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.console.reader < input1.txt lines=2, encoding=UTF-8 0 ® C2:AE 1 ࠁ E0:A0:81 % ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.in < input1.txt lines=2, encoding=UTF-8 0 ® C2:AE 1 ࠁ E0:A0:81 input1.txt is generated as follows: import java.io.FileWriter; import java.io.IOException; public class GenerateInput1 { public static void main(String[] args) throws IOException { try (var f = new FileWriter("input1.txt")) { f.write("\u00AE\n\u0801\r"); } } }
06-11-2023

Attached files to help reproduce the behaviour. The hexdump of the file generated by GenerateInput should look like this: 00000000 61 62 63 0d 64 65 66 0a 67 68 69 0d 0a 6a 6b 6c |abc.def.ghi..jkl| 00000010 On macOS Sonoma (14.0 (23A344)), a fresh mainline OpenJDK build (377138c7b58) behaves as follows: ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.in < input.txt lines=4, encoding=UTF-8 0 abc 61:62:63 1 def 64:65:66 2 ghi 67:68:69 3 jkl 6A:6B:6C % ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.console.reader < input.txt lines=4, encoding=UTF-8 0 abc 61:62:63 1 def 64:65:66 2 ghi 67:68:69 3 jkl 6A:6B:6C % ~/jdk/build/macosx-aarch64/images/jdk/bin/java ReadInput.java system.console.readline < input.txt lines=2, encoding=UTF-8 0 abcdef 61:62:63:64:65:66 1 ghi 67:68:69
06-11-2023