javajava.util.scannernosuchelementexception

java.util.NoSuchElementException: no Line found from the Java Scanner


I am creating a quiz game which has one Player instance that the user can create once and then edit the username in Java. My issue comes with my use of the Scanner (I'm pretty sure) which for some reason does not find a new line to read from. My code gives me the following error:

Exception in thread "main" java.util.NoSuchElementException: No line found
        at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
        at Player.setUsername(Player.java:33)
        at Quiz.printPlayerEditor(Quiz.java:118)
        at Run.main(Run.java:20)

Here is the method setUsername within Player.java that gives error, this is then used in another method printPlayerEditor from Quiz.java, which is then used in the main (Run.java):

public void setUsername(Scanner in) {
    String user = "";

    do {
        while (!in.hasNextLine() && !user.isEmpty() && user.length() < 16 ) {
            Quiz.printError();
            in.next();
        }
        user = in.nextLine(); //Line 33
        username = user;
        Quiz.setProperties("playerusername", username);

    }while(!username.equals(user));
}

The Quiz.java code that gives error (which uses the previous method)

public void printPlayerEditor(Scanner in) {
    System.out.println("<><><><><><><><><><><><><><><><><><><><><><><>");
    System.out.println("Welcome to the Player editor:");
    System.out.println("Your current username is | " + player.getUsername() + " |");
    System.out.println("Please enter a new username between 1-16 characters:");
    System.out.println("<><><><><><><><><><><><><><><><><><><><><><><>");

    player.setUsername(in);

    System.out.println("Your username is now | " + player.getUsername() + " |\n");
}

And then lastly this is used in the main in a switch case that deals with the input. This is where the Scanner comes from:

import java.util.Scanner;

public class Run {
    public static void main(String[] args) {        
        Quiz quiz = new Quiz();
        Player player = new Player();

        quiz.setPlayer(player);
        quiz.populateQuestions();
        int input = quiz.printMenu1();

        Scanner in = new Scanner(System.in);

        switch (input) {                
            case 1:
                if (Quiz.getProperties("playerusername").isEmpty()) {
                    quiz.printPlayerCreator(in);
                    input = 2;
                } else {
                    quiz.printPlayerEditor(in);
                    input = 2;
                }
                
            case 2: 
                try {
                    quiz.printUnitMenu(in);

                } catch (NullPointerException e) {
                    quiz.printPlayerCreator(in);
                
                }
                break;

            default:
                Quiz.printError();
                quiz.printMenu1();
                break;
        }

        in.close();
        
    }
}

I've tried passing the same scanner into all of them, and I've tried making the classes static and stuff, but I'm still quite new to Java and cannot get my head around why this error may be occurring.


Solution

  • Do not ever close resources that you aren't responsible for. You are not responsible for System.in (in fact, you should never close that unless you really know what that means and are sure you want to do that), and 'wrapper' resources (Such as Scanner, generally created with new ResourceThing(refToSomeOtherResource)), if you close them, close the thing you wrapped. In other words - don't.

    Some linting tools tell you that you should be closing a resource. Those linting tools are incorrect. (somewhat understandably, keeping track of filters 'through' the resource they wrap is a bit complex).