Java Runtime.exec()

Java Runtime.exec(),java,Java,我可以从命令行毫无问题地运行此命令(验证脚本执行): 如果我不使用URL参数,只需执行以下操作: String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" }; Runtime r = Runtime.getRuntime(); Process p = r.exec(args1); 它很好用。如果我使用某些URL作为参数,例如: String[] args1 = {"c:/Pytho

我可以从命令行毫无问题地运行此命令(验证脚本执行):

如果我不使用URL参数,只需执行以下操作:

String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" };
Runtime r = Runtime.getRuntime();
Process p = r.exec(args1);
它很好用。如果我使用某些URL作为参数,例如:

String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.intertwingly.net/blog/index.atom"};
// or 
String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.cnn.com"};
它也很好用

但是如果我使用这个特定的URL,那么脚本就会挂起(java等待进程完成)。我不知道为什么它可以从该URL的命令行工作,但不能从java程序工作。我尝试在URL参数周围添加引号,但也不起作用。我在URL中没有看到任何我认为需要转义的字符

完整代码:

String urlToValidate = "https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators";

String[] args1 = {"c:/Python27/python", "C:/Documents and Settings/vhaiswcaldej/DAS_Workspace/feedvalidator/feedvalidator/src/demo.py", urlToValidate };
System.out.println(args1[0] + " " + args1[1] + " " + args1[2]);

Runtime r = Runtime.getRuntime();
Process p = r.exec(args1);
BufferedReader br = new BufferedReader(new InputStreamReader(
p.getInputStream()));
int returnCode = p.waitFor();
 System.out.println("Python Script or OS Return Code: " + Integer.toString(returnCode));
if (returnCode >= 2) {
    .out.println("OS Error: Unable to Find File or other OS error.");
    }

String line = "";
while (br.ready()) {
     String str = br.readLine();
     System.out.println(str);
     if (str.startsWith("line")) {
     //TODO: Report this error back to test tool.
     //System.out.println("Error!");
     }
     }

您需要排出进程的输出和错误流,否则当执行的程序产生输出时,它将阻塞

从:

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能会导致子流程阻塞,甚至死锁


您需要排出进程的输出和错误流,否则当执行的程序产生输出时,它将阻塞

从:

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能会导致子流程阻塞,甚至死锁

读取(并关闭)
p.getInputStream()
p.getErrorStream()

例如:

// com.google.common.io.CharStreams
CharStreams.toString(new InputStreamReader(p.getInputStream()));
CharStreams.toString(new InputStreamReader(p.getErrorStream()));
读取(并关闭)
p.getInputStream()
p.getErrorStream()

例如:

// com.google.common.io.CharStreams
CharStreams.toString(new InputStreamReader(p.getInputStream()));
CharStreams.toString(new InputStreamReader(p.getErrorStream()));

人们通常会被Java中的exec例程挂起所捕获。我也曾被那件事吓坏过。问题是,您试图执行的进程可能(取决于很多事情)首先写入stdOut或stdErr。如果你按错误的顺序处理它们,exec将被挂起。要正确处理此问题,您必须创建两个线程来同时读取stdErr和stdOut。例如:

Process proc = Runtime.getRuntime().exec( cmd );

// handle process' stdout stream
Thread out = new StreamHandlerThread( stdOut, proc.getInputStream() );
out.start();

// handle process' stderr stream
Thread err = new StreamHandlerThread( stdErr, proc.getErrorStream() );
err.start();

exitVal = proc.waitFor(); // InterruptedException

...

out.join();
err.join();

人们通常会被Java中的exec例程挂起所捕获。我也曾被那件事吓坏过。问题是,您试图执行的进程可能(取决于很多事情)首先写入stdOut或stdErr。如果你按错误的顺序处理它们,exec将被挂起。要正确处理此问题,您必须创建两个线程来同时读取stdErr和stdOut。例如:

Process proc = Runtime.getRuntime().exec( cmd );

// handle process' stdout stream
Thread out = new StreamHandlerThread( stdOut, proc.getInputStream() );
out.start();

// handle process' stderr stream
Thread err = new StreamHandlerThread( stdErr, proc.getErrorStream() );
err.start();

exitVal = proc.waitFor(); // InterruptedException

...

out.join();
err.join();


也许当前的目录很重要?您可以尝试切换到命令行中的另一个目录。您应该检查在Linux-
ps f
、Win-sysinternals ProcessExplorer上从Java执行的实际命令行。这可能是ssl问题。您可以尝试调用http端点来验证它吗?您是否在创建进程后调用进程的p.waitFor()方法?exec应该是非阻塞的,因此如果不调用waitFor,您可能会锁定代码中的其他地方,因为创建的进程尚未完成执行。请将其用双引号括起来,如
String[]args1={“c:/Python27/python”、“./feedvalidator/feedvalidator/src/demo.py”、“\”https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators\""};也许当前目录很重要?您可以尝试切换到命令行中的另一个目录。您应该检查在Linux-
ps f
、Win-sysinternals ProcessExplorer上从Java执行的实际命令行。这可能是ssl问题。您可以尝试调用http端点来验证它吗?您是否在创建进程后调用进程的p.waitFor()方法?exec应该是非阻塞的,因此如果不调用waitFor,您可能会锁定代码中的其他地方,因为创建的进程尚未完成执行。请将其用双引号括起来,如
String[]args1={“c:/Python27/python”、“./feedvalidator/feedvalidator/src/demo.py”、“\”https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators\""};我没有看到该进程的排放方法。我实际运行的代码是什么?我已经用完整的代码更新了这个问题。。。;in.skip(in.available());输入流错误=。。。;err.skip(err.available())@user994165有一个用于排出流的示例代码,我没有看到该流程的排出方法。我实际运行的代码是什么?我已经用完整的代码更新了这个问题。。。;in.skip(in.available());输入流错误=。。。;err.skip(err.available())@user994165有一个使用redirectErrorStream排出流的示例代码是一个好得多的主意:使用redirectErrorStream是一个好得多的主意:如果输出大于Java的堆内存怎么办?虽然我想在大多数情况下,你知道不会。如果您编写这样的方法,然后在忘记此限制后将其用于生成大输出的对象,则可能会出现问题。@EvgeniSergeev是的,用另一种方式读取并关闭它们,我刚才提到了它们作为示例。如果输出大于Java的堆内存,该怎么办?虽然我想在大多数情况下,你知道不会。如果您编写这样的方法,然后在忘记此限制后将其用于生成大输出的对象,则可能会出现问题。@EvgeniSergeev是的,请以另一种方式阅读并关闭它们,我刚才提到了它们作为示例。