Eclipse IDE中的java.io.Console支持


103

我使用Eclipse IDE来开发,编译和运行Java项目。今天,我试图使用java.io.Console该类来管理输出,更重要的是,管理用户输入。

问题是当“通过” Eclipse运行应用程序时System.console()返回null。Eclipse在后台进程上运行该程序,而不是在我们熟悉的控制台窗口中的顶级进程上运行。

有没有一种方法可以强制Eclipse将程序作为顶级进程运行,或者至少创建JVM将识别的控制台?否则,我不得不将项目压缩并在Eclipse外部的命令行环境中运行。


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

我将项目导出为可运行的jar,但仍收到控制台null错误
Abhigyan

Answers:


50

我假设您希望能够使用Eclipse的逐步调试。您可以通过在JRE类路径的bin目录中设置构建的类来在外部运行这些类。

java -cp workspace\p1\bin;workspace\p2\bin foo.Main

您可以使用远程调试器进行调试,并利用项目中内置的类文件。

在此示例中,Eclipse项目结构如下所示:

workspace\project\
                 \.classpath
                 \.project
                 \debug.bat
                 \bin\Main.class
                 \src\Main.java

1.在调试模式下启动JVM控制台

debug.bat是Windows批处理文件,应从cmd.exe控制台在外部运行。

@ECHO OFF
SET A_PORT=8787
SET A_DBG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=%A_PORT%,server=y,suspend=y
java.exe %A_DBG% -cp .\bin Main

在参数中,调试端口已设置为8787。在暂停= Y参数告诉JVM等到调试程序连接。

2.创建调试启动配置

在Eclipse中,打开“调试”对话框(运行>打开调试对话框...),并使用以下设置创建新的远程Java应用程序配置:

  • 项目:您的项目名称
  • 连接类型:标准(插座连接)
  • 主机: localhost
  • 港口: 8787

3.调试

因此,您想要调试该应用程序的所有时间是:

  • 设定一个断点
  • 在控制台中启动批处理文件
  • 启动调试配置

您可以在错误122429中跟踪此问题。您可以通过使用此处所述的抽象层来解决应用程序中的此问题。


1
我还将pause在该批处理文件的末尾放置一个,以便您可以看到在关闭之前闪烁的所有错误消息。
马特·里昂斯

10
这是我的最后一根稻草。如果必须调试所有这些操作,那么我将切换回Netbeans。Eclipse中有许多未修复的错误和UI烦恼,这甚至不很有趣。
nuzzolilo 2012年

@Nuzzolilo,这仅用于远程调试。您可以在Eclipse中进行本地调试而无需所有这些。
Laplie Anderson

35

我使用的解决方法是在使用Eclipse时仅使用System.in/System.out而不是Console。例如,代替:

String line = System.console().readLine();

您可以使用:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();

20
我认为您无法通过这种方式屏蔽密码来读取密码。
Sualeh Fatehi 2011年

3
...还有一个需要处理的情况IOException,如果发生则不会抛出Console.readLine()
dma_k 2011年

5

发生这种情况的原因是因为eclipse将您的应用程序作为后台进程而不是系统控制台的顶级进程来运行。


5

您可以自己实现一个类。以下是一个示例:

public class Console {
    BufferedReader br;
    PrintStream ps;

    public Console(){
        br = new BufferedReader(new InputStreamReader(System.in));
        ps = System.out;
    }

    public String readLine(String out){
        ps.format(out);
        try{
            return br.readLine();
        }catch(IOException e)
        {
            return null;
        }
    }
    public PrintStream format(String format, Object...objects){
        return ps.format(format, objects);
    }
}

4

http://www.stupidjavatricks.com/?p=43找到了有关此内容的信息

遗憾的是,由于控制台是最终版本,因此您无法对其进行扩展以在system.in和system.out周围创建一个包装器。即使在eclipse控制台内部,您仍然可以访问它们。这可能就是为什么eclipse尚未将其插入其控制台的原因...

我理解为什么您除了System.console之外,没有其他方法,不想拥有任何其他方式来获得控制台,但是我不明白为什么您不希望有人能够重写该类来制作控制台。模拟/测试控制台...


4

另一个选择是创建一种方法来包装两个选项,并在Console不可用时“故障转移”到System.in方法。下面的示例是一个非常基本的示例-您可以按照相同的过程在控制台中包装所需的其他方法(readPassword,格式)。这样,您就可以在Eclipse中愉快地运行它,并在部署它时获得控制台功能(例如,密码隐藏)。

    private static String readLine(String prompt) {
        String line = null;
        Console c = System.console();
        if (c != null) {
             line = c.readLine(prompt);
        } else {
            System.out.print(prompt);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            try {
                 line = bufferedReader.readLine();
            } catch (IOException e) { 
                //Ignore    
            }
        }
        return line;
    }

2

据我所知,无法从Eclipse获取Console对象。我只是确保控制台!= null,然后将其JAR起来并从命令行运行它。


1

通过Eclipse运行应用程序时,似乎无法获得java.io.Console对象。命令行控制台窗口未与应用程序一起打开,因为它是作为后台进程(Eclipse的背景吗?)运行的。当前,没有Eclipse插件可以处理此问题,主要是由于java.io.Console是最终类。

您真正能做的就是测试返回的Console对象是否为null,然后从那里继续。


1

链接提供了使用System.console()的替代方法。一种是使用环绕System.in的BufferedReader,第二种是使用环绕System.in的Scanner。

两者都没有控制台那么简洁,但是两者都可以在eclipse中工作,而不必求助于调试愚蠢的事情!


0

假设您的Eclipse工作区是C:\ MyWorkspace,您在maven项目MyProject中创建了Java应用程序,而Java主类是com.mydomain.mypackage.MyClass。

在这种情况下,您可以运行System.console()在命令行上使用的主类:

java -cp C:\MyWorkspace\MyProject\target\classes com.mydomain.mypackage.MyClass

注意:如果不在Maven项目中,请检查项目属性中的输出文件夹| Java构建路径 资源。它可能不是“目标/类”

NB2:如果这是一个Maven项目,但是您的班级在src / test / java中,则可能必须使用“ target \ test-classes”而不是“ target \ classes”

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.