简体   繁体   English

Java Runtime.exec()以运行Java程序

[英]Java Runtime.exec() to run a java program

Here's the situation. 这是情况。 Im creating a UI which will allow make using a genetic programming system (ECJ) easier to use. 我创建了一个UI,使使用基因编程系统(ECJ)的操作更加容易。

Currently you need to run a command prompt within the ECJ folder and use the commands similar to this to execute a parameter file. 当前,您需要在ECJ文件夹中运行命令提示符,并使用与此类似的命令来执行参数文件。

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

Where the full path of tutorial5 is tutorial5的完整路径在哪里

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

and the command prompt must be executed from 并且命令提示符必须从

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

My program makes the user select a .params file (which is located in a ecj subdirectory) and then use the Runtime.exec() to execute 我的程序使用户选择一个.params文件(位于ecj子目录中),然后使用Runtime.exec()执行

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

What i have so far 我到目前为止有什么

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

Currently it outputs the change directory command but nothing else. 当前,它输出更改目录命令,但没有其他输出。 Can this be done? 能做到吗?

First, the 'cd' command can't be executed by Runtime.exec() in the first place (see How to use "cd" command using Java runtime? ). 首先,首先不能由Runtime.exec()执行'cd'命令(请参阅如何使用Java运行时使用“ cd”命令? )。 You should be able to just set the working directory for the process when you call exec (see below). 您应该能够在调用exec时为进程设置工作目录(见下文)。

Second, running 'cmd.exe /c' to execute your process isn't what you want here. 其次,运行“ cmd.exe / c”来执行您的过程不是您想要的。 You won't be able to get the results of your process running, because that is returned to the command window -- which eats the error and then closes without passing the error along to you. 您将无法获得流程运行的结果,因为该结果将返回到命令窗口,该窗口将吞噬错误,然后关闭而不将错误传递给您。

Your exec command should look more like this: 您的exec命令应如下所示:

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

Where 'command' looks like this: 其中“命令”如下所示:

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

Edit: For reading error messages, try this: 编辑:对于读取错误消息,请尝试以下操作:

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

Each call to exec() runs in a new environment, this means that the call to cd will work, but will not exist to the next call to exec() . 每次对exec()调用都在新环境中运行,这意味着对cd的调用将起作用,但对下一次对exec()调用将不存在。

I prefer to use Apache's Commons Exec , it's provides an excellent facade over Java's Runtime.exec() and gives a nice way to specify the working directory. 我更喜欢使用Apache的Commons Exec ,它提供了Java的Runtime.exec()的出色外观,并提供了一种指定工作目录的好方法。 Another very nice thing is they provide utilities to capture standard out and standard err. 另一个非常棒的事情是,它们提供了捕获标准输出和标准错误的实用程序。 These can be difficult to properly capture yourself. 这些可能很难正确地捕捉自己。

Here's a template I use. 这是我使用的模板。 Note that this sample expects an exit code of 0, your application may be different. 请注意,此示例期望退出代码为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...
}

You can use Java processbuilder: processBuilder documentation ! 您可以使用Java processbuilderprocessBuilder文档
you can define the working directory of the process and all other stuff. 您可以定义流程的工作目录以及所有其他内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM