Java Runtime.exec() 到 运行 一个 java 程序
Java Runtime.exec() to run a java program
情况是这样的。我正在创建一个 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
我的程序使用户 select 成为一个 .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");
}
目前它输出更改目录命令,但没有别的。
这能做到吗?
您可以使用 Java processbuilder:
processBuilder documentation!
您可以定义进程的工作目录和所有其他内容。
首先,'cd' 命令不能由 Runtime.exec() 首先执行(参见 How to use "cd" command using Java runtime?)。您应该能够在调用 exec 时为进程设置工作目录(见下文)。
其次,运行 'cmd.exe /c' 执行您的流程并不是您想要的。您将无法获得过程 运行 的结果,因为它会返回到命令 window —— 它会吃掉错误,然后在不将错误传递给您的情况下关闭。
您的 exec 命令应该更像这样:
Process p = Runtime.getRuntime().exec(
command, null, "C:\Users\Eric\Documents\COSC\ecj");
其中 'command' 看起来像这样:
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!");
}
对 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...
}
情况是这样的。我正在创建一个 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
我的程序使用户 select 成为一个 .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");
}
目前它输出更改目录命令,但没有别的。 这能做到吗?
您可以使用 Java processbuilder:
processBuilder documentation!
您可以定义进程的工作目录和所有其他内容。
首先,'cd' 命令不能由 Runtime.exec() 首先执行(参见 How to use "cd" command using Java runtime?)。您应该能够在调用 exec 时为进程设置工作目录(见下文)。
其次,运行 'cmd.exe /c' 执行您的流程并不是您想要的。您将无法获得过程 运行 的结果,因为它会返回到命令 window —— 它会吃掉错误,然后在不将错误传递给您的情况下关闭。
您的 exec 命令应该更像这样:
Process p = Runtime.getRuntime().exec(
command, null, "C:\Users\Eric\Documents\COSC\ecj");
其中 'command' 看起来像这样:
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!");
}
对 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...
}