2

Consider I have a Java (or Kotlin, doesn't really matter) application which uses java.io.Console API, or any other API which manipulates the terminal state (e.g.: net.rubygrapefruit:native-platform):

System.out.println(format("Console is %s.", System.console()));

final Terminals terminals = Native.get(Terminals.class);
final Output out = Stdout;
if (terminals.isTerminal(out)) {
    final TerminalOutput stdout = terminals.getTerminal(out);
    stdout.bold();
    System.out.println("bold text");
    stdout.foreground(Color.Magenta);
    System.out.println("Magenta");
    stdout.reset();

    final Prompter prompter = new Prompter(terminals);
    prompter.askYesNo("Prompt", true);
    prompter.enterText("Text", "default text");
    prompter.enterPassword("Password");
    prompter.select("Select", asList("foo", "bar", "baz"), 1);
} else {
    System.out.println(format("%s is not a terminal.", out));
}

The above code would run just fine when launched by Maven Exec plug-in, but with Gradle (since Gradle tries to make its own output look pretty, with all those bells, whistles and progress bars) the code just prints:

$ gradle --console=plain run
> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE

> Task :run
Console is null.
Stdout is not a terminal.

BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date

Configuring the run task as described here and here:

private val run: JavaExec by tasks
run.apply {
    standardInput = System.`in`
    standardOutput = System.out
    errorOutput = System.err
}

or adding --no-daemon to Gradle's command line args as suggested here doesn't really help (System.in is still an instance of java.io.PipedInputStream, while System.out and System.err are instances of org.gradle.internal.io.LinePerThreadBufferingOutputStream).

Is it possible to make Gradle stop messing with the terminal and allow the application being run to access it?

Bass
  • 4,977
  • 2
  • 36
  • 82

1 Answers1

0

You're probably assigning them wrongfully, because these both should be ByteArrayOutputStream. And probably they should not even be assigned in Gradle (the assignment of default values is redundant). Use Exec and then execute java -jar fileName, if you shouldn't get it working with JavaExec.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216