JDK-8348052 : java.io.Console in JDK >= 22 emits unexpected/unwanted escape sequences
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 24
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2025-01-15
  • Updated: 2025-03-07
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
ADDITIONAL SYSTEM INFORMATION :
Ubuntu 24.04 amd64, Oracle OpenJDK 23.0.1 amd64

A DESCRIPTION OF THE PROBLEM :
Starting with OpenJDK Java 22 Java programs using java.io.Console cannot be tested with dejagnu test framework<LINK1> any more. With JDK 21 it works like a charm.
It has to do with escape sequences that are emitted/inserted by java.io.Console.readLine() to the result. I already have filed a bug to the dejagnu project<LINK2>, however, it turned out that the problem is on the JDK side.
Consider the simple Java program testsuite/simple.sh in section source code for an executable test. It shows a prompt and simply prints all input until an input of "quit" is made. Starting the program with dejagnu, which simply enters a string "hello" as input. Then the echo of the result Of Console.readline() shows/contains some escape sequences were no one are expected:

^[[?1h^[=^[[?2004hhello
^[[?1l^[>^[[?1000l^[[?2004lhello

Thus the test which simply checks the output on exact equality to "hello" fails.

However, windows console/linux console/bash/EclipseIDE internal "console"/IntelliJ internal "console" seems to "suppress"/not show this escape sequences. It is no option that dejagnu suppresses/interprets them, as it explicitly can test on escape sequences as the maintainer tell. DejaGnu exposes this issue because it is strict about matching exactly what you tell it to match.

REGRESSION : Last worked in version 21.0.5

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
For an easy reproduction I have created small example simple.zip, downloadable via <LINK3>
First install package dejagnu, e.g., on Debian or Ubuntu with apt-get install dejagnu. That's easy, I use Ubuntu 24.04 but, that should not matter. Then just unpack the downloaded zip and execute exectest.sh. Be sure to update JAVA_HOME in this script to point to your jdk 23 installation.
Now see the result in testsuite/simple.log (do not use cat on the shell as it does not show the escape sequences -> use some test editor, e.g., mcedit or emacs work), or see the paste of this file in section actual result.

EXPECTED RESULT
Test run by chris on Tue Jan 14 11:26:39 2025
Native configuration is x86_64-pc-linux-gnu

                === simple tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /export/scratch/chris/Console/simple/testsuite/config/default.exp as tool-and-target-specific interface file.
spawn ./simple.sh
prompt> Running /export/scratch/chris/Console/simple/testsuite/simple.tests/echo.exp ...
hello
hello
prompt> PASS: hello
testcase /export/scratch/chris/Console/simple/testsuite/simple.tests/echo.exp completed in 0 seconds
quit
PASS: quit

                === simple Summary ===

# of expected passes            2
runtest completed at Tue Jan 14 11:26:40 2025


ACTUAL RESULT
Test run by chris on Tue Jan 14 11:39:10 2025
Native configuration is x86_64-pc-linux-gnu

                === simple tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /export/scratch/chris/Console/simple/testsuite/config/default.exp as tool-and-target-specific interface file.
spawn ./simple.sh
prompt> Running /export/scratch/chris/Console/simple/testsuite/simple.tests/echo.exp ...
^[[?1h^[=^[[?2004hhello
^[[?1l^[>^[[?1000l^[[?2004lhello
prompt> ^[[?1h^[=^[[?2004h
FAIL: hello (expected "hello")
testcase /export/scratch/chris/Console/simple/testsuite/simple.tests/echo.exp completed in 0 seconds
quit
^[[?1l^[>^[[?1000l^[[?2004lexpect: spawn id exp6 not open
    while executing
...


The test "hello" fails. (For the same reason the following "quit" test also fails and dejgnu shows wired error messages. Please ignore content in testsuite/simple.log after the line starting with FAIL so far.)

SOURCE CODE FOR AN EXECUTABLE TEST CASE


#!/usr/bin/env -S java --source 23
// #!/usr/local/java/jdk-23.0.1/bin/java --source 23 -Djdk.console=java.base

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ConsoleTest {
    public static void main(String[] args) throws IOException {
        boolean quit = false;
        while (!quit) {
            System.out.print("prompt> ");

            java.io.Console in = System.console();
            // BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

            String input = in.readLine();
            if (input.equals("quit")) {
                quit = true;
            } else {
                System.out.println(input);
            }
        }
    }
}


WORKAROUND
Everything works after simply commenting the line java.io.Console in = System.console(); and uncommenting the following line replacing it with the good old BufferedReader in testsuite/simple.sh. Alternatively it also works by passing -Djdk.console=java.base to the jvm (1st line in testsuite/simple.sh), to enable the older Console implementation in JDK. 

Comments
Additional Information from submitter: ============================== Definitely, the the returned String from Console.readLine() includes those escape sequences. Thus it is a bug in Console.readLine(). However, as far I can see, there is no possibility to to simply reproduce that on a classical terminal/console/IDE as there it seems that the escape sequences are suppressed. The dejagnu framework has a simpler "console". As already written, I talked with the maintainer of dejagnu and he tells that definitely dejagnu does not add or suppress any escape sequences as one can test on them with expect/dejagnu, see text in my posting. > Those escapes are generated by JLine underneath, so the displayed text > in the actual terminal by `expect` command may vary. That is the problem: So JLine (as part of JDK) adds them to the input of Console.readLine()? The input should NOT be changed! Please reopen the bug report again, I think it is a rather crucial one/regression which needs a fix.
17-02-2025

Can the submitter please clarify if the returned String from Console.readLine() includes those escape sequences? If so, it is a bug in Console, otherwise it is not something JDK can control over. Those escapes are generated by JLine underneath, so the displayed text in the actual terminal by `expect` command may vary.
10-02-2025

Additional Information from submitter: =========================================== For an easy reproduction I have created small example simple.zip, downloadable via <LINK3>
21-01-2025