java.util.scanner throws NoSuchElementException when application is started with gradle run

I have a created a simple java "echo" application that takes a user's input and shows it back to them to demonstrate the issue. I can run this application without trouble using IntelliJ's internal "run" command, and also when executing the compiled java file produced by gradle build. However, if I try to execute the application using gradle run, I get a NoSuchElementException thrown from the scanner.

I think gradle or the application plugin specifically is doing something strange with the system IO.

Application

package org.gradle.example.simple;

import java.util.Scanner;

public class HelloWorld {
  public static void main(String args[]) {
    Scanner input = new Scanner(System.in);
    String response = input.nextLine();
    System.out.println(response);
  }
}

build.gradle

apply plugin: 'java'
version '1.0-SNAPSHOT'

apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'org.gradle.example.simple.HelloWorld'
    }
}

apply plugin: 'application'

mainClassName = "org.gradle.example.simple.HelloWorld"

sourceCompatibility = 1.5

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

Any ideas how to make this application work using gradle run?


Solution 1:

You must wire up default stdin to gradle, put this in build.gradle:

run {
    standardInput = System.in
}

UPDATE: 9 Sep 2021

As suggested by nickbdyer in the comments run gradlew run with --console plain option to avoid all those noisy and irritating prompts

Example

gradlew --console plain run

And if you also want to completely get rid of all gradle tasks logs add -q option

Example

gradlew -q --console plain run

Solution 2:

In addition to the accepted answer: If you who are using the Gradle Kotlin DSL instead of the normal Groovy DSL, you have to write the following:

tasks {
    run {
        standardInput = System.`in`
    }
}

Additional note: I had a similar problem in a Spring Boot application. There, I had to modify the bootRun task instead of the run task.