17

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?

nickbdyer
  • 564
  • 5
  • 13

2 Answers2

32

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

run{
    standardInput = System.in
}
Humberto Pinheiro
  • 974
  • 11
  • 17
  • 7
    This works great, and for anyone that is annoyed by the ugly prompt that now appears `gradle --console plain run` removes it. There is an open issue https://issues.gradle.org/browse/GRADLE-1147 for this, where I found that snippet. – nickbdyer Apr 19 '16 at 20:22
  • 3
    If not using the application plugin, the `standardInput = System.in` line should go within whatever task you are running that needs stdin redirected to it. For me it was within a custom [JavaExec](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.JavaExec.html) task. – Dylan Nissley Aug 14 '16 at 20:07
  • Dude it doesn't work in my run script. Can you explain more? – Alireza Mohamadi Dec 04 '16 at 19:43
  • You just put that snippet in build.gradle and type gradle run, whats the error you got ? – Humberto Pinheiro Dec 05 '16 at 18:52
  • 3
    Could not find method run() for arguments [build_70djsz9uqda5dtwfrqrhv32tu$_run_closure3@446452bb] on root project of type org.gradle.api.Project. – Chinmay Mar 29 '19 at 19:31
  • @AlirezaMohamadi make sure you have `id 'application'` in your build.gradle `plugins { }` block – Pranav A. Mar 26 '20 at 18:31
1

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.

Markus Weninger
  • 8,844
  • 4
  • 47
  • 112