-1

I am working on a Java project that includes a simple menu system. I am getting some strange errors when the code reaches folling line in the Menu() function:

int menuInput = Integer.parseInt(scanner.nextLine()); 

I have seen similar issues that people have posted, but nothing I do seems to fix the issue. I have posted the full class below.

package Compiler;

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.io.IOException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("Copy and paste code to be compiled here, then press ENTER followed by CTRL+D:\n");

        CharStream input = CharStreams.fromStream(System.in);
        GrammarLexer lexer = new GrammarLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        GrammarParser parser = new GrammarParser(tokens);
        ParseTree tree = parser.program();
        Worker worker = new Worker(parser.getRuleNames());
        worker.visit(tree);
        Menu(worker);
    }

    private static void Menu(Worker worker) {
        while (true) {
            System.out.println("1-4?");

            Scanner scanner = new Scanner(System.in);
            int menuInput = Integer.parseInt(scanner.nextLine());   // THIS IS WHERE THE CODE CRASHES

            try {
                switch(menuInput) {
                    case 1: {
                        worker.PrintParseTree();
                        break;
                    } case 2: {
                        String searchQuery = scanner.nextLine();
                        worker.SearchParseTree(searchQuery);
                        break;
                    } case 3: {
                        worker.PrintJSCode();
                        break;
                    } case 4: {
                        worker.PrintWACode();
                        break;
                    } default: {
                        System.out.println("ERROR: Invalid input, please try again...");
                        break;
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

This is the error that continues to occur. The code crashes before giving the user opportunity to make any input:

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
    at Compiler.Main.Menu(Main.java:44)
    at Compiler.Main.main(Main.java:29)

Update: From looks of things from ANTLR website, the fromStream method will open the System.in stream, then closes it (see quote from website).

Creates a CharStream given an opened InputStream containing UTF-8 bytes. Reads the entire contents of the InputStream into the result before returning, then closes the InputStream.

Can anybody provide a workaround for this?

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
J. Whitehead
  • 451
  • 4
  • 21
  • 1
    Does this answer your question? [java.util.NoSuchElementException: No line found](https://stackoverflow.com/questions/7209110/java-util-nosuchelementexception-no-line-found) – esqew Apr 06 '20 at 14:26
  • No, i am asking why this is happening, as the code does not give the opportunity for the uswe to input anything, it just crashes – J. Whitehead Apr 06 '20 at 14:48
  • @SoftwareEngineer it does not fix the issue, I have already tried – J. Whitehead Apr 06 '20 at 15:22
  • As i said. I think it is the second line in the main function causing problems, as any scanner used before that line works, but any after do not. – J. Whitehead Apr 06 '20 at 15:44

1 Answers1

0

I think somewhere inside of the worker methods you close the CharStream input, which closes System.in, which means there are no more lines for the scanner to read.

Edit:

I don't have access to the CharStream class, so I substited it for InputStreamReader in my example. The following code gives the same error that yours does.

//When the program starts, System.in is open.

InputStreamReader is = new InputStreamReader(System.in);
is.close(); 
// When we close the InputStreamReader, the underlying System.in is also closed.

Scanner scanner = new Scanner(System.in); 
//It successfully creates a scanner for System.in, even if it's closed.

scanner.nextLine();
//But it can't read, since the underlying stream is now closed.

I'm not concerned about instances of System.in.close(), but rather input.close() which also affects System.in. input may of course have a different name in different classes.

Dejke
  • 168
  • 1
  • 9
  • The input stream is not touched within the worker class. – J. Whitehead Apr 06 '20 at 14:47
  • Does it break on the first or second iteration? – Dejke Apr 06 '20 at 14:49
  • First iteration. It crashes before allowing the user to make any input. – J. Whitehead Apr 06 '20 at 14:51
  • If it breaks on the first, you likely closed the input object in a constructor before. – Dejke Apr 06 '20 at 14:51
  • Surely it must be open as I am declaring the scanner 1 line above – J. Whitehead Apr 06 '20 at 14:58
  • I have searched my entire project, and the only references to System.in are in the code I show, plus one time where I declare another scanner in the Worker – J. Whitehead Apr 06 '20 at 15:02
  • This can go as an answer (of questionable helpfulness). No need to jump into the face of people by blatantly quoting the rule you think you are breaking. Luckily, with some extended tolerance, you are not actually breaking the rule. For other occasions, please understand that the rule applies to you, even if you quote it. https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead – Yunnosch Apr 06 '20 at 15:22
  • I apologize for that, and for any additional moderation work it caused. @J.Whitehead I have edited the answer with an example to clarify – Dejke Apr 06 '20 at 16:09