Hello,

This existing email thread seems to hold the most historical context
regarding usability of Console in jshell.

On 12/07/22 15:52, Naoto Sato wrote:
> On Tue, 29 Nov 2022 19:38:02 GMT, Naoto Sato <naoto at openjdk.org> wrote:
>> This is to allow Console to be used even when it is not attached
> to the platform provided terminal, such as the case when the
> standard input is redirected. `System.console()` now returns
> a Console implementation based on `jdk.internal.le` terminal by default,
> or jshell implementation if available. A corresponding CSR has been
> drafted.
> This pull request has now been integrated.
> Changeset: 8a9911ef
> Author:    Naoto Sato <naoto at openjdk.org>
> URL:
https://git.openjdk.org/jdk/commit/8a9911ef1762ae837e427ec9d91b1399ba33b6e4
> Stats:     684 lines in 17 files changed: 661 ins; 11 del; 12 mod
> 8295803: Console should be usable in jshell and other environments
> Reviewed-by: jlaskey, alanb
> PR: https://git.openjdk.org/jdk/pull/11421


Since integration of 8295803, it is possible to use Console in jshell
*when using jshell interactively*.

When jshell is reading from a script file, it remains impossible to use
readLine or readPassword of Console. This is the case whether the script
file being read from is supplied as jshell's standard input, or is named
on the command line, or is named with /open in an interactive session.

It is perhaps least astonishing to have the Console not work when standard
input is redirected (though I'm not aware of a modern OS where the console
can't be identified even when stdin happens to be redirected). On the other
hand, it is quite astonishing when the opening of a script file by name
interferes with use of the console.

The upshot is that a common expectation of a scripting language--that it
be able to solicit some user input or a password while executing
a script--remains unmet in jshell even with the integration of 8295803.

At first glance, it appears to me there is no very fundamental problem,
except that Console operations are vectored through an IOContext, and
the ScannerIOContext put in place while reading from a script does not
accommodate them. There may have been a bit of conceptual conflation
around whether a NonInteractiveIOContext (perhaps only meaning the
commands being executed are sourced from a file) must be the same thing
as a context with no access to a console for soliciting input.

Prior to JDK 24, an attempt to use readLine or readPassword results in
an uncaught exception that terminates the state engine:

Exception in thread "output reader"
jdk.internal.org.jline.reader.UserInterruptException
        at
jdk.jshell/jdk.internal.jshell.tool.IOContext.readPassword(IOContext.java:75)
        at
jdk.jshell/jdk.internal.jshell.tool.JShellTool$IOContextConsole.readPassword(JShellTool.java:4114)
        at
jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:410)
        at java.base/java.io.OutputStream.write(OutputStream.java:167)
        at java.base/java.io.OutputStream.write(OutputStream.java:124)
        at
jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
State engine terminated.

As of JDK 24, there is no uncaught exception, but readLine / readPassword
simply return null, after displaying the supplied prompt.

The behavior change for JDK 24 appears to have been included without
explanation in an unrelated commit for JDK-8341631:

https://github.com/openjdk/jdk24u/commit/cf158bc6cdadfdfa944b8ec1d3dc7069c8f055a9#diff-0ec20a2b27010e8ce642a3f62fdb25fee623b0e4c564f4f49bedeabf7b0a7107R4110-R4137

It may be that the changes (catching the exception and returning null)
were a preliminary stage of an effort to make readLine / readPassword
actually work; the intention just isn't clear from that commit message.

Regards,
Chapman Flack

Reply via email to