Skip to content

No need to explicitly use javaw on Windows #642

@urmuzov

Description

@urmuzov

My app has different subcommands, one of which launches Lanterna UI. This required me to have a launcher .bat file on windows, that selects java or javaw depending on the command.

Recenly I noticed that debugger in IntelliJ IDEA uses java.exe, but launches SwingTerminalWindow correctly.

After debugging, the difference I found is in behaviour of DefaultTerminalFactory.hasTerminal:

  • On Windows form cmd: true
  • On Linux (WSL in my case): true
  • In IntelliJ debugger: false

So in this function (see comments inline):

    @Override
    public Terminal createTerminal() throws IOException {
        // 3 different reasons for tty-based terminal:
        //   "explicit preference", "no alternative",
        //       ("because we can" - unless "rather not")
        if (forceTextTerminal || isAwtHeadless() ||
                (hasTerminal() && !preferTerminalEmulator) ) {
            return createHeadlessTerminal(); // <--- Windows and Linus go into this branch
        }
        else {
            // while Lanterna's TerminalEmulator lacks mouse support:
            // if user wanted mouse AND set a telnetPort, and didn't
            //   explicitly ask for a graphical Terminal, then go telnet:
            if (!preferTerminalEmulator && mouseCaptureMode != null && telnetPort > 0) {
                return createTelnetTerminal();
            } else {
                return createTerminalEmulator(); // <--- App started with debugger goes into this branch
            }
        }
    }

On windows it enters createHeadlessTerminal and later fails in createWindowsTerminal with "To start java on Windows, use javaw! (see https://github.com/mabe02/lanterna/issues/335 )"

So basically what I did is replaced:

        this.terminal = new DefaultTerminalFactory().createTerminal();

with

        Terminal t;
        try {
            t = new DefaultTerminalFactory().createTerminal(); // <--- Linux and debugger use this branch
        } catch (IOException e) {
            t = new DefaultTerminalFactory().setPreferTerminalEmulator(true).createTerminal(); // <--- Windows uses this branch
        }
        this.terminal = t;

in my code, and now I can remove java/javaw switching logic and whole .bat file alltogether. As far as I tested - everything works just fine.

Are there any downsides to this approach? Maybe createTerminal() should not fail with "To start java on Windows, use javaw! (see https://github.com/mabe02/lanterna/issues/335 )" if we actually can create SwingTerminalWindow without using javaw?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions