107

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

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

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

4

10 回答 10

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

在参数中,调试端口已设置为8787suspend=y参数告诉 JVM 等到调试器附加。

2. 创建调试启动配置

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

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

3. 调试

因此,只要您想调试应用程序,您所要做的就是:

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

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

于 2008-09-19T20:37:36.253 回答
34

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

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

您可以使用:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
于 2010-12-20T16:54:14.990 回答
5

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

于 2008-09-19T18:40:06.800 回答
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);
    }
}
于 2013-03-21T04:22:13.387 回答
4

在http://www.stupidjavatricks.com/?p=43找到了一些关于此的内容。

可悲的是,由于控制台是最终的,你不能扩展它来创建一个围绕 system.in 和 system.out 的包装器。即使在 Eclipse 控制台中,您仍然可以访问这些控制台。这可能就是为什么 eclipse 还没有将它插入他们的控制台的原因......

我理解为什么您不希望有任何其他方式来获得 System.console 以外的控制台,没有设置器,但我不明白为什么您不希望有人能够覆盖该类来制作一个模拟/测试控制台...

于 2008-09-19T18:49:07.683 回答
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;
    }
于 2012-08-17T01:46:58.683 回答
2

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

于 2008-09-19T18:37:41.377 回答
1

通过 Eclipse 运行应用程序时,似乎无法获取 java.io.Console 对象。命令行控制台窗口不会随应用程序一起打开,因为它作为后台进程运行(Eclipse 的后台?)。目前,没有 Eclipse 插件来处理这个问题,主要是因为 java.io.Console 是一个 final 类。

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

于 2008-09-19T18:56:36.540 回答
1

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

两者都不像控制台那样简洁,但两者都可以在 Eclipse 中工作,而无需求助于愚蠢的调试!

于 2012-07-11T11:05:27.197 回答
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

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

NB2:如果它是一个 maven 项目,但你的类在 src/test/java 中,你可能不得不使用“target\test-classes”而不是“target\classes”

于 2017-02-09T14:35:38.873 回答