【问题标题】:Java Runtime.exec() to run a java programJava Runtime.exec() 运行一个java程序
【发布时间】:2015-06-21 20:38:21
【问题描述】:

情况是这样的。我正在创建一个 UI,它可以让遗传编程系统 (ECJ) 更易于使用。

目前您需要在 ECJ 文件夹中运行命令提示符,并使用与此类似的命令来执行参数文件。

java ec.Evolve -file ec\app\tutorial5\tutorial5.params

tutorial5的完整路径在哪里

C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params

并且命令提示符必须从

执行
C:\Users\Eric\Documents\COSC\ecj

我的程序让用户选择一个 .params 文件(位于 ecj 子目录中),然后使用 Runtime.exec() 执行

java ec.Evolve -file ec\app\tutorial5\tutorial5.params

到目前为止我有什么

// Command to be executed
String cmd = "cd " + ecjDirectory;        
String cmd2 = "java ec.Evolve -file " + executeDirectory;


System.out.println(cmd);
try {
    Process p = Runtime.getRuntime().exec(
                new String[]{"cmd.exe", "/c", cmd, cmd2});
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    statusTF.append(r.readLine());
    p.waitFor();        

    } catch (IOException | InterruptedException ex) {
        System.out.println("FAILED: " + ex.getMessage());
        statusTF.append("Failed\n");
    }

目前它只输出更改目录命令,但没有别的。 这个可以吗?

【问题讨论】:

  • 程序是否以错误结束或只是在 exec() 命令后挂起?
  • try 语句无错误结束

标签: java command prompt runtime.exec


【解决方案1】:

首先,'cd' 命令不能由 Runtime.exec() 执行(参见How to use "cd" command using Java runtime?)。当您调用 exec 时,您应该能够只设置进程的工作目录(见下文)。

其次,运行 'cmd.exe /c' 来执行你的进程并不是你想要的。您将无法获得进程运行的结果,因为它会返回到命令窗口——它会吃掉错误然后关闭而不将错误传递给您。

您的 exec 命令应该看起来更像这样:

Process p = Runtime.getRuntime().exec(
    command, null, "C:\Users\Eric\Documents\COSC\ecj");

“命令”如下所示:

String command = "java ec.Evolve -file ec\app\tutorial5\tutorial5.params"

编辑:要阅读错误消息,请尝试以下操作:

String error = "";
try (InputStream is = proc.getErrorStream()) {
    error = IOUtils.toString(is, "UTF-8");
}
int exit = proc.waitFor();
if (exit != 0) {
    System.out.println(error);
} else {
    System.out.println("Success!");
}

【讨论】:

  • 我已更改此设置,因为我在传递目录的字符串值时遇到错误。进程 p = Runtime.getRuntime().exec(cmd2, null, new File(ecjDirectory));它可以工作,但我无法知道它何时完成执行,有时我调用的结果在我终止程序之前不会完成执行。
  • error = IOUtils.toString(is, "UTF-8");给我错误。退出没有发生,因为我认为正在运行的文件没有提供退出代码。应用程序锁定,直到我关闭程序,我运行的命令的最终结果才完成并显示它们的结果。
  • 好的,再试一件事……在 Runtime.getRuntime().exec() 之后直接调用:proc.getOutputStream().close();
  • proc.getOutputStream().close() 确保进程不会坐在那里等待查看是否有更多用户输入——这可能就是这里发生的事情。
【解决方案2】:

您可以使用 Java 进程构建器: processBuilder documentation
您可以定义进程的工作目录和所有其他内容。

【讨论】:

    【解决方案3】:

    exec() 的每次调用都在新环境中运行,这意味着对cd 的调用将起作用,但对exec() 的下一次调用将不存在。

    我更喜欢使用Apache's Commons Exec,它比Java 的Runtime.exec() 提供了一个出色的外观,并提供了一种指定工作目录的好方法。另一个非常好的事情是它们提供了捕获标准输出和标准错误的实用程序。这些可能很难正确捕捉到自己。

    这是我使用的模板。请注意,此示例要求退出代码为 0,您的应用程序可能会有所不同。

    String sJavaPath = "full\path\to\java\executable";
    String sTutorialPath = "C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params";
    String sWorkingDir = "C:\Users\Eric\Documents\COSC\ecj";
    
    try (
            OutputStream out = new ByteArrayOutputStream();
            OutputStream err = new ByteArrayOutputStream();
        )
    {
        // setup watchdog and stream handler
        ExecuteWatchdog watchdog = new ExecuteWatchdog(Config.TEN_SECONDS);
        PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
    
        // build the command line
        CommandLine cmdLine = new CommandLine(sJavaPath);
        cmdLine.addArgument("ec.Evolve");
        cmdLine.addArgument("-file");
        cmdLine.addArgument(sTutorialPath);
    
        // create the executor and setup the working directory
        Executor exec = new DefaultExecutor();
        exec.setExitValue(0); // tells Executor we expect a 0 for success
        exec.setWatchdog(watchdog);
        exec.setStreamHandler(streamHandler);
        exec.setWorkingDirectory(sWorkingDir);
    
        // run it
        int iExitValue = exec.execute(cmdLine);
    
        String sOutput = out.toString();
        String sErrOutput = err.toString();
        if (iExitValue == 0)
        {
            // successful execution
        }
        else
        {
            // exit code was not 0
            // report the unexpected results...
        }
    }
    catch (IOException ex)
    {
        // report the exception...
    }
    

    【讨论】:

    • 你好......你能给我们提供你使用这个模板执行一个java应用程序并在控制台上打印它的输出的java代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多