System.console()返回null


78

我曾经使用readLineofBufferedReader来获取用户的输入/新密码,但想屏蔽该密码,所以我尝试使用java.io.Consoleclass。问题是在Eclipse中调试应用程序时System.console()返回null。我是Java和Eclipse的新手,不确定这是否是最好的方法吗?我右键单击源文件,然后选择“调试为”>“ Java应用程序”。有什么解决方法吗?


1
另请参见stackoverflow.com/questions/26470972/…我确定了System.outSystem.in足以满足我的用例,并使用放弃了System.console()
OneWorld'7

Answers:



33

这个代码片段应该可以解决这个问题:

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();
}

在Eclipse中进行测试时,您的密码输入将清晰显示。至少,您将能够进行测试。只是不要在测试时输入您的真实密码。保留供生产使用;)。


您的手动readLine方法是否应该BufferedReader在finally(或try-with-resources)块中关闭?
安德鲁·斯旺

否,因为那样会关闭匹配System.in流,并且之后无法再进行读取。
formixian

是的,可以关闭此流很奇怪;我希望这不会发生。
安德鲁·斯旺


8

当尝试编写一个简单的命令行应用程序时,我也遇到了这个问题。

从System.in创建自己的BufferedReader对象的另一种方法是使用java.util.Scanner,如下所示:

import java.util.Scanner;

Scanner in;
in = new Scanner(System.in);

String s = in.nextLine();

当然,这将不是Console的直接替代,而是使您可以访问各种不同的输入功能。

这是来自Oracle的有关Scanner更多文档


7

根据文档

如果虚拟机是自动启动的(例如由后台作业调度程序启动),则该虚拟机通常将没有控制台。


1
这个答案使我发现,如果在启用了守护程序的情况下运行Gradle,您将无法在Gradle任务中获得控制台。使用'--no-daemon'运行我的Gradle任务可以访问控制台。
whitespy9 2015年

这在我对命令行工具使用点滴(github.com/ninjudd/drip)时发生了。糟糕!
乔治L

7

根据API

“如果从交互式命令行启动虚拟机而不重定向标准输入和输出流,则其控制台将存在,并且通常会连接到键盘并显示启动虚拟机的位置。如果启动虚拟机自动,例如由后台作业调度程序自动执行,则通常没有控制台。”


4

从Netbeans运行应用程序时收到此错误消息。从其他答案来看,这似乎是从IDE运行应用程序时发生的。如果您看一下这个问题:尝试从Java控制台中读取,那是因为

大多数IDE使用javaw.exe而不是java.exe来运行Java代码

解决方案是使用command line/terminal来获取Console


1

我相信,在Eclipse的运行配置中,您可以配置是否分配控制台-确保已选中。(自从我使用Eclipse已经有一段时间了,所以我无法给出具体的说明,我担心)。

如果这不起作用,那么肯定可以完成此工作的操作是以调试方式启动应用程序,然后使用Eclipse连接到该进程。如果不确定如何执行此操作,请搜索“ Eclipse远程调试”。

此外,总的来说,要求分配一个控制台是一个坏主意,因为这会极大地影响应用程序的灵活性-正如您刚刚发现的那样。许多调用Java的方法不会分配控制台,并且您的应用程序在这些实例中不可用(这很糟糕)。也许您可以选择在命令行上指定参数。(如果您专门测试控制台输入,那么就足够公平了,但是对于人们来说,能够从脚本和/或无头服务器上调用您的应用程序可能很有用,因此这种灵活的设计几乎总是一个好主意。 。它通常也会导致组织更好的代码。)


是的,它仅用于调试目的,用户将获得shell脚本或bat文件。使用控制台难道不是吗?如果是的话,还有什么更好的方法
高卢(Gauls)2010年

顺便说一句,所有远程调试搜索都在讨论Web服务器,但是我没有创建Web应用程序。这是一个普通的java。可能是屏蔽密码的更好方法?
高卢

您可以远程调试任何Java进程,只需-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000在VM的参数中添加例如(至少在Sun JVM上)。可以使用控制台,但是要指出的是,如果不使用控制台,则代码根本无法正常工作。相反,考虑通过从命令行参数,系统属性,属性文件等直接采购在价值最起码提供了一些可供选择-例如,只能去到控制台,如果值作为命令行参数提供。
Andrzej Doyle 2010年

1

我参考并使用了上面显示的formixian答案。关键是使用(黑色)cmd控制台按照“ ojonugwa ochalifu”的建议运行Java程序。

**


0

没错

您将必须在Eclipse之外运行该应用程序。查看Eclipse中的启动器配置面板,看看是否可以找到在单独的JVM中运行命令的选项。


0

如果您的IDE使用javaw而不是java,则肯定会发生此问题,因为javaw本质上是没有控制台窗口的Java。


-1

在程序参数中添加-console以启动OSGi控制台


1
如果可能的话,请您进一步说明一下吗?
高卢

我今天学到了一些新东西,谢谢。但是,eclipse仍从内部控制台内部读取参数。因此,您提出的解决方案将无法解决原始问题。
Kiswanij
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.