Exception in thread "main" java.util.NoSuchElementException

Hi,
I am using the MacOS Terminal and getting the following output when gradle-ing my exercises.groovy file:

:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:exercises
Exception in thread "main" java.util.NoSuchElementException
	at java.util.Scanner.throwFor(Scanner.java:862)
	at java.util.Scanner.next(Scanner.java:1371)
	at java.util.Scanner.next(Scanner.java:304)
	at java_util_Iterator$next.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
	at exercises.run(exercises.groovy:2)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:848)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:831)
	at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:407)
	at org.codehaus.groovy.runtime.InvokerHelper$runScript.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
	at exercises.main(exercises.groovy)
:exercises FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':exercises'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.688 secs

I tried to look in the Gradle dist’s samples folder but I can’t find any reference nor to java.util.Scanner, nor to java.util to mimic the settings…

This is the simple code I am trying to run:

Scanner scn = new java.util.Scanner(System.in);
String str = scn.next();

This is my build.gradle:

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'application'

repositories {
    jcenter()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.1.0'
}

task exercises (dependsOn: 'classes', type: JavaExec) {
    main = 'exercises'
    classpath = sourceSets.main.runtimeClasspath
}

Cheers,
N

JavaExec launches a Java process with System.in connected to /dev/null, basically. There won’t be any input available.

Scanner scn = new java.util.Scanner(System.in);
String str = scn.next();

scn is going to be reading from a empty input stream, so scn.next() will fail since there’s nothing in the scanner.

JavaExec launches a Java process with System.in connected to /dev/null. There won’t be any input available.

Can you point me to where I can read more about this kind of issues and how to fix them? Thank you.

It depends on what you want to do. JavaExec is a Gradle thing. The Scanner and System.in are built-in JDK things.

There’s not a good way to get standard input to a JavaExec task without disabling the Gradle daemon. The easiest thing to do might be to apply the application plugin and run the script that’s generated by that outside of Gradle. Then System.in will be the regular console input.

Picking up on your suggestion, I found this Stackoverflow topic and a post on this very forum where this solution is given:

Per default the system.in of your gradle build is not wired up with the system.in of the run (JavaExec) task. You can do the following:

run{
    standardInput = System.in
}

After adding it as the last line of my build.gradle and running gradle <task> the error is still the same though:

Exception in thread "main" java.util.NoSuchElementException

What do you think it should do?

I though it would make the System.in available to any JavaExec task specified in the build.gradle when build.gradle is executed. I guess not though. :slight_smile:

Also I tried adding the line to the task itself:

task exercises (dependsOn: 'classes', type: JavaExec) {
    main = 'exercises'
    classpath = sourceSets.main.runtimeClasspath
    standardInput = System.in
}

But it gets stuck on 80%:

:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
> Building 80% > :exercises

This actually seems to work! I just need to type in something :))

Also I had added this line:

mainClassName = ' '

I hope I am doing things right and it is not just a random case of success…

The NoSuchElementException in Java is thrown when one tries to access an iterable beyond its maximum limit. This means that, this exception is thrown by various accessor methods to indicate that the element being requested does not exist . The next() method in Java returns the next element in the iteration or NoSuchElementException if the iteration has no more elements.

As with most programming languages, the Iterator class includes a hasNext() method that returns a boolean indicating if the iteration has anymore elements. If hasNext() returns true, then the next() method will return the next element in the iteration otherwise raise exceptions if the iteration has no more elements.

if(input.hasNextInt() )
     number1 = input.nextInt(); // if there is another number  
else 
     number1 = 0; // nothing added in the input

I though it would make the System.in available to any JavaExec task specified in the build.gradle when build.gradle is executed. I guess not though.

Accually you can :smile:. I’m using gradle 6.5.1 and I added this to my gradle.build

run {
    standardInput(System.in)
}

For me it was also stuck at 80% but it turned out it’s because it was waiting for me to type the input.