50

I have just started learning Java with IntelliJ IDE. I know a bit C# so the logic makes some sense, however there is one thing so far I couldn't get over it.

How do I read from the console? In C#, you could easily read what the human typed into it, using Console.ReadLine(). In Java, System.console().readLine(); does not work for me and throws a NullPointerException.

What am I missing here?

Makoto
  • 104,088
  • 27
  • 192
  • 230
LidorA
  • 627
  • 1
  • 6
  • 7
  • 1
    Look into the `Scanner` class, it should give you what you're looking for. – AntonH Oct 20 '14 at 16:58
  • 1
    First result for googling last words from title of your question: "read from console JAVA" gives: [Java: How to get input from System.console()](http://stackoverflow.com/questions/4644415/java-how-to-get-input-from-system-console). Also `System.console().readLine();` works fine for me (if I run my code via console, outside of IDE). We need to see your code and know how are you using it and what exception you are getting. – Pshemo Oct 20 '14 at 17:02
  • possible duplicate of [Reading and writing to console in Java](http://stackoverflow.com/questions/1746181/reading-and-writing-to-console-in-java) – Basil Bourque Oct 20 '14 at 19:08

7 Answers7

86

NOTE: problem doesn't appear when we run your code from console/terminal via java [options] [MainClass] so if this is valid solution for you you can stop reading here. Rest of this answer is for people who are using some IDEs to run their code.

Problem

Most IDEs are using javaw.exe instead of java.exe to run Java code (see image below).

Difference between these two programs is that javaw runs Java code without association with current terminal/console (which is useful for GUI applications), and since there is no associated console window System.console() returns null. Because of that System.console().readLine() ends up as null.readLine() which throws NullPointerException since null doesn't have readLine() method (nor any method/field).

But just because there is no associated console, it doesn't mean that we can't communicate with javaw process. This process still supports standard input/output/error streams, so IDEs process (and via it also we) can use them via System.in, System.out and System.err.

This way IDEs can have some tab/window and let it simulate console.

For instance when we run code like in Eclipse:

package com.stackoverflow;

public class Demo {

    public static void main(String[] args) throws Exception {
        System.out.println("hello world");
        System.out.println(System.console());
    }

}

we will see as result

enter image description here

which shows that despite javaw.exe not having associated console (null at the end) IDE was able to handle data from standard output of the javaw process System.out.println("hello world"); and show hello world.

General solution

To let user pass information to process use standard input stream (System.in). But since in is simple InputStream and Streams are meant to handle binary data it doesn't have methods which would let it easily and properly read data as text (especially if encoding can be involved). That is why Readers and Writers ware added to Java.

So to make life easier and let application read data from user as text you can wrap this stream in one of the Readers like BufferedReader which will let you read entire line with readLine() method. Unfortunately this class doesn't accept Streams but Readers, so we need some kind of adapter which will simulate Reader and be able to translate bytes to text. But that is why InputStreamReader exists.

So code which would let application read data from input stream could look like

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello. Please write your name: ");
String name = br.readLine();
System.out.println("Your name is: "+name);

Preferred/simplest solution - Scanner

To avoid this magic involving converting Stream to Reader you can use Scanner class, which is meant to read data as text from Streams and Readers.

This means you can simply use

Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();

to read data from user (which will be send by console simulated by IDE using standard input stream).

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • 22
    If one is trying to use `Console.readPassword()`, the fact that most IDEs don't supply a `Console` is a killer. `java.io.InputStream`, `java.io.Reader`, `java.io.Console`, and `java.util.Scanner` all descend directly from `java.lang.Object` and have no interfaces in common. – Urhixidur Jun 08 '17 at 14:12
  • 3
    Interestingly, `java.exe` provides `System.console()!=null` when ran from the command line, but provides `System.console()==null` whan ran from the Eclipse IDE (tried with Oracle JDK9/JDK10 and Eclipse Neon3) – Julien Kronegg Nov 24 '18 at 20:37
  • I was getting this error: `java.util.NoSuchElementException: No line found`. The solution was run the main class instead of a gradle task – Maurici Abad Oct 01 '19 at 14:58
1

Normally, the Console object requires a valid tty provided by an operating system, but IntelliJ IDEA output window does not provide one. It's not very trivial to do this in OS-independent way. Not only IntelliJ IDEA is affected. You cannot use System.console() in jshell as well:

|  Welcome to JShell -- Version 17.0.6
|  For an introduction type: /help intro

jshell> System.console()
$1 ==> null

jshell>

In Java 20, this issue was partially addressed. Now, you can add a VM option -Djdk.console=jdk.internal.le. Go to 'Edit Run/Debug configurations', then Modify Options, Add VM Options and type it there. After that the System.console() will work inside IDE. It will be hooked to System.in which IDE already intercepts.

Note that this solution is undocumented and unsupported, so may not work in future Java versions. You can find more information in this JDK issue.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
0

If you realy need to Console object you can compile your class from command line. Firstly in my java file first statement is package com.inputOutput;

Go in your project "src" folder and compile it like : "javac com/inputOutput/Password.java" 'com' and 'inputOutput' are folder(package). Run your class file in src folder
java com.inputOutput.Password". It had worked work for me.

Muhammed Ozdogan
  • 5,341
  • 8
  • 32
  • 53
0

You could use an Jframe.

JFrame frame = new JFrame("titile");

// prompt the user to enter their code
String code = JOptionPane.showInputDialog(frame, "promt here");
Kerwin Sneijders
  • 750
  • 13
  • 33
宏杰李
  • 11,820
  • 2
  • 28
  • 35
0

I abstracted it out, so when running in an IDE, it will use the scanner, but when running from the command line, it'll use the console:

import java.io.Console;
import java.util.Scanner;
    
public class UserInputReader {
  private final Console console;
  private final Scanner scanner;

  public UserInputReader() {
    console = System.console();
    scanner = console == null ? new Scanner(System.in) : null;
  }

  public String readLine() {
    return console != null ? console.readLine() : scanner.nextLine();
  }
    
  public String readPassword() {
    return console != null ? String.valueOf(console.readPassword()) : scanner.nextLine();
  }
}
Craigo
  • 3,384
  • 30
  • 22
0

As a workaround I start a terminal from my project in intellij then I type:

$ java -cp target/classes org.enricogiurin.ocp17.ch14.UserInput

Where UserInput is the class whose main uses the java.io.Console.

I know it's not the expected solution, in fact I have written that it's a workaround.

Enrico Giurin
  • 2,183
  • 32
  • 30
-3

java.util.Scanner API is what you are looking for.

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Nagakishore Sidde
  • 2,617
  • 1
  • 16
  • 9
  • 4
    Any explanations about why Scanner is what OP should use? What about other alternatives like BufferedReader? Also `System.console()` will also work if it is used properly. – Pshemo Oct 20 '14 at 17:04
  • Scanner API is a very simple API for reading the console inputs. It is very easy to get a hang of it, esp for the beginners. To start using the BufferedReader API, user should be aware of quite a few java.io related interfaces and the exact differences among them. It takes some time to get a hang of it and appreciate it. At least, that is what happened to me when there was no Scanner API, before java-1.5 – Nagakishore Sidde Oct 20 '14 at 17:17
  • There's another answer here explaining scanner in detail with example: https://stackoverflow.com/a/26473083/6693304 – KulaGGin Mar 02 '21 at 11:22