Skip to content

Conversation

@gbrail
Copy link
Collaborator

@gbrail gbrail commented Dec 15, 2025

The "tools" module has a bunch of code that tries to use reflection to load a nice console using JLine when it's in the classpath.

Now that our codebase is modular, do this in a nicer way by creating a new top-level "rhino-cli" module for this. Include this module in "rhino-all" so that the default experience has a nice CLI.

Update the various "tools" programs to load the JLine console if it is available, and if it is not, or not on an interactive terminal, fall back to the old-fashioned console based on System.in and System.out.

This does add JLine as a dependency in "rhino-all." If this is an issue for users, we could "shade" it using a plugin, or we could just suggest that folks who don't want a full-fledged CLI use the new modules instead of "rhino-all" and not include the new CLI module if they don't want it.

This doesn't carry forward the old completer code that we used to have -- I didn't find that to work reliably with the current JLine. There's room for future improvement there.

Replace the old code that tried to use reflection to load a JLine
console with a new "rhino-cli" module that includes JLine. If this
module is present and we are on an interactive terminal, we will use a
JLine console which supports command history and editing.
Include this module in rhino-all so that the default Rhino CLI uses it.
@gbrail gbrail marked this pull request as ready for review December 15, 2025 06:31
@gbrail
Copy link
Collaborator Author

gbrail commented Dec 15, 2025

This might be helpful to some of you, it certainly improves the experience for me, I'd love it if a few people could try it out.

@aardvark179
Copy link
Contributor

This looks pretty good—though we will need to ensure we don't pull in JLine on our fork. You might want to tweak the default run cradle task a little because it run the REPL without JLine.

@Override
public boolean isSupported() {
// Only allow JLine to be used if we have full functionality.
return (terminal != null
Copy link
Contributor

@ZZZank ZZZank Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if old behaviour is good behaviour, but I think it is possible to avoid changing it, by doing something like this:

private final Optional<Terminal> terminal; // type in generic param so that at runtime JVM will load `Optional.class` instead of `Terminal.class`

public JLineConsoleProvider() {
    try {
        terminal = Optiona.of(...);
    } catch (Throwable t) {
        // capture `Throwable`, including `NoClassDefFoundError` when JLine is not present
        terminal = Optional.empty();
    }
}

And by doing so we can merge rhino-cli into rhino-tools because JLine can be compileOnly dependency

(please ignore the fact that I targeted this comment at line 34 for no reason)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants