为什么System.console()为命令行应用程序返回null?

我正在开发一个依赖于用户命令行输入的遗留应用程序:

String key = System.console().readLine("Please enter the license key: "); 

但是,我得到一个NullPointerException因为System.console()给我一个null。

为什么System.console()为命令行应用程序返回null? 当它从终端以及IDE运行时会发生这种情况。

如果你从终端窗口启动java,那么它确实应该工作,即使我还没有尝试过OSX。

如果你直接从终端使用java运行一个简单的测试,它有用吗?

 echo 'public class Test { public static void main(String[] args) {System.console().printf("hello world%n");}}' >Test.java && javac Test.java && java Test 

预期产量:

 hello world 

如果它不起作用,那么抱歉,您的平台上没有控制台支持。

但是,如果它工作,并且您的程序没有,那么程序的启动方式就会出现问题。

检查java二进制文件的启动方式? 它是从shell脚本开始的吗? 检查stdin / stdout是否未被重定向或管道输入某些内容,还可能是它未在后台启动。

例如:这可能会使System.console()返回null。

 java Test | tee >app.log 

和这个:

 java Test >/tmp/test.log 

这似乎适用于我的机器(linux)

 java Test & 

即使在几个gc和终结器之后,似乎System.setOutSystem.setErrSystem.setIn也不会影响控制台。


然而:

关闭(原始) System.outSystem.in也将禁用console

 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 

预期产量:

 Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:1) 

所以; 扫描代码以查找关闭流的地方,或者将System.out传递给可能关闭的地方。

要从标准输入(命令行输入)读取,必须使用某种流读取器来读取System.in流。 由InputStreamReader初始化的

  InputStreamReader(System.in) 

让你逐字逐句阅读。 但是,我建议用BufferedReader包装它:

  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String inputLine = reader.readLine(); 

必须导入

  java.io.*;