【问题标题】:java.io.Console support in Eclipse IDEEclipse IDE 中的 java.io.Console 支持
【发布时间】:2010-09-11 09:08:23
【问题描述】:

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

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

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

【问题讨论】:

  • 另见stackoverflow.com/questions/26470972/… 我确定System.outSystem.in 足以满足我的用例,并使用System.console() 放弃。
  • 我将项目导出为可运行的 jar,但我仍然收到控制台 null 错误

标签: java eclipse console java-io


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          我假设您希望能够在 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 应用程序配置:

          • 项目:你的项目名称
          • 连接类型:标准(Socket Attach)
          • 主机: 本地主机
          • 端口: 8787

          3.调试

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

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

          您可以在bug 122429 中跟踪此问题。您可以使用here 所述的抽象层在您的应用程序中解决此问题。

          【讨论】:

          • 我还会在该批处理文件的末尾添加一个pause,这样您就可以看到在它关闭之前闪现的任何错误消息。
          • 这是压垮我的最后一根稻草。如果我必须做所有这些只是为了调试,我将切换回 Netbeans。 Eclipse 中有这么多未修复的错误和 UI 烦恼,这甚至都不好笑。
          • @Nuzzolilo,这仅用于远程调试。您可以在 eclipse 中进行本地调试,而无需所有这些。
          【解决方案6】:

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

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

          你可以使用:

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

          【讨论】:

          • 我认为您无法通过这种方式读取带有密码屏蔽的密码。
          • ... 并且需要处理IOException,在Console.readLine()的情况下不会抛出。
          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

            另一个选项是创建一个方法来包装这两个选项,并在控制台不可用时“故障转移”到 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;
                }
            

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                【解决方案10】:

                假设您的 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”

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-10-24
                  • 1970-01-01
                  • 2014-01-16
                  • 1970-01-01
                  • 2011-09-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多