This is a bug #122429 of eclipse
Answer from swimmingfisher on Stack OverflowThis is a bug #122429 of eclipse
This code snippet should do the trick:
private String readLine(String format, Object... args) throws IOException {
if (System.console() != null) {
return System.console().readLine(format, args);
}
System.out.print(String.format(format, args));
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
return reader.readLine();
}
private char[] readPassword(String format, Object... args)
throws IOException {
if (System.console() != null)
return System.console().readPassword(format, args);
return this.readLine(format, args).toCharArray();
}
While testing in Eclipse, your password input will be shown in clear. At least, you will be able to test. Just don't type in your real password while testing. Keep that for production use ;).
If you start java from a terminal window, then it really should work, even though I haven't tried on OSX.
If you run a simple test using java directly from the terminal, does it work?
echo 'public class Test { public static void main(String[] args) {System.console().printf("hello world%n");}}' >Test.java && javac Test.java && java Test
Expected output:
hello world
If it doesn't work, then sorry, no console support on your platform.
However, if it works, and your program doesn't then there is a problem with how your program is started.
Check how the java binary started? Is it started from a shell script? Check that stdin/stdout have not been redirected or piped into something, and possibly also that it's not started in the background.
ex: This will probably make System.console() return null.
java Test | tee >app.log
and this:
java Test >/tmp/test.log
This seems to work on my machine (linux)
java Test &
Neither does it seem as if System.setOut, System.setErr or System.setIn affects the console, even after a couple of gc's and finalizers.
However:
Closing (the original) System.out or System.in will disable the console too.
echo 'public class Test { public static void main(String[] args) {System.out.close();System.console().printf("hello world%n");}}' >Test.java && javac Test.java && java Test
Expected output:
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:1)
So; scan your code for places where it closes streams, or passes System.out somewhere it might get closed.
To read from Standard input (command line input) you must use some kind of stream reader to read the System.in stream. An InputStreamReader initialised by
InputStreamReader(System.in)
lets you read character by character. However, I suggest wrapping this with a BufferedReader:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String inputLine = reader.readLine();
Must import
java.io.*;
From the Javadoc:
Returns the unique Console object associated with the current Java virtual machine, if any.
If there is no console associated to the JVM, the pointed line is the call of a method on a null object, hence the exception.
How do you launch your application?
Whether a virtual machine has a console is dependent upon the underlying platform and also upon the manner in which the virtual machine is invoked. If the virtual machine is started from an interactive command line without redirecting the standard input and output streams then its console will exist and will typically be connected to the keyboard and display from which the virtual machine was launched. If the virtual machine is started automatically, for example by a background job scheduler, then it will typically not have a console.
If you want to read the username from the standard input, you could use this code:
try {
System.out.print("Enter Username: ");
InputStreamReader streamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(streamReader);
String username = bufferedReader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
That is because System.console()is returning null. The official documentation states (bold is mine to emphasize):
public static Console console()
Returns the unique Console object associated with the current Java virtual machine, if any.
Returns: The system console, if any, otherwise null.
You can see it here.
Stephen C's answer: "Read the Java 22 release notes. There is a section that explains what has changed ... and what to do rather than testing if 'console()' returns 'null.'" Helped me. He left it as a comment so I'm replying with an answer to make sure it's preserved and so people have to do less manual digging but the credit goes to him.
The JDK 22 release notes say that System.console() will no longer return null when the standard streams are redirected or connected to a virtual terminal. Instead the Console.isTerminal() method allows you to check if the console is connected to a terminal.
Console console = System.console();
if(!console.isTerminal()) {
//code goes here...
}
Additionally running with -Djdk.console=java.base will restore the old functionality
It looks like System.console() is not behaving as expected in your environment, possibly because of how the JVM or IDE is configured. Sometimes, when running Java applications from IDEs or certain environments, System.console() may not return null even if the application isn't actually being run from a terminal.
Here’s an alternative approach to determine if your Java application is running in a terminal or not:
Using System.getenv() and System.getProperty()
You can use environment variables and system properties to infer whether your application is running in a terminal.
- On Windows, the presence of the
COMSPECenvironment variable typically indicates a terminal or command prompt environment. - On Unix-like systems, the presence of the
TERMenvironment variable suggests that the application might be running in a terminal.
private static boolean isRunningInTerminal() {
// Check if environment variables typically set for terminals are present
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) {
String comSpec = System.getenv("COMSPEC");
return comSpec != null && !comSpec.isEmpty();
} else {
String term = System.getenv("TERM");
return term != null && !term.isEmpty();
}
}
You could also check for the presence of specific system properties or runtime configurations that are indicative of running in a terminal environment. add additional debugging outputs to understand the environment better:
System.out.println("Console: " + System.console());
System.out.println("COMSPEC: " + System.getenv("COMSPEC"));
System.out.println("TERM: " + System.getenv("TERM"));
System.out.println("OS Name: " + System.getProperty("os.name"));
System.out.println("OS Version: " + System.getProperty("os.version"));
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("User Directory: " + System.getProperty("user.dir"));
System.out.println("Current Working Directory: " + System.getProperty("user.dir"));
This will help you determine what environment variables and properties are available, and why System.console() might not be returning null.
Because it is a bug #122429 of eclipse
System.console() returns null if there is no console.
You can work round this either by adding a layer of indirection to your code or by running the code in an external console and attaching a remote debugger.
Also, According to the docs:
If the virtual machine is started automatically, for example by a background job scheduler, then it will typically not have a console.