简体   繁体   English

Java Runtime.exec()

[英]Java Runtime.exec()

I can run this command from the command line without any problem (the validation script executes): 我可以从命令行运行此命令,而不会出现任何问题(执行验证脚本):

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 

and from java if I leave off the URL parameter and just do: 从java,如果我离开URL参数,只是做:

String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" };
Runtime r = Runtime.getRuntime();
Process p = r.exec(args1);

it works fine. 它工作正常。 If I use certain URLs for a parameter such as: 如果我使用某些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"};

it also works fine. 它也可以正常工作。

But if I use this particular URL https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators , then the script just hangs (java waits for the process to finish). 但是,如果我使用这个特定的URL https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators ,则脚本会挂起(java等待过程完成)。 I'm not sure why it works from the command line for that URL but not from a java program. 我不确定为什么它可以从该URL的命令行运行,而不是从Java程序运行。 I tried adding quotes to surround the URL parameter but that didn't work either. 我尝试添加引号将URL参数括起来,但这也不起作用。 I don't see any character in the URL that I think need to be escaped. 我认为URL中没有任何需要转义的字符。

Full Code: 完整代码:

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

You need to drain the output and error streams of the process, or else it will block when the executed program produces output. 您需要耗尽进程的输出和错误流,否则当执行的程序产生输出时,它将阻塞。

From the Process documentation : 流程文档中

Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock. 由于某些本机平台仅为标准输入和输出流提供了有限的缓冲区大小,因此无法及时写入子流程的输入流或读取子流程的输出流可能导致子流程阻塞,甚至死锁。

Read (and close) p.getInputStream() and p.getErrorStream() . 读取(并关闭) p.getInputStream()p.getErrorStream()

For example: 例如:

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

People usually got caught by exec routine hangs in Java. 人们通常被exec例程挂在Java上。 I was cought by that once too. 我也曾经被那件事困扰过。 The problem is that the process you are trying to execute may (depending on lot of things) either first write to stdOut or stdErr. 问题在于您尝试执行的过程可能(取决于很多事情)可能首先写入stdOut或stdErr。 If you handle them in wrong order exec will hang. 如果您以错误的顺序处理它们,则exec将挂起。 To handle this properly always you must create 2 threads to read stdErr and stdOut simulteneously . 为了始终正确处理此问题,您必须创建2个线程以同时读取stdErr和stdOut Sth like: 像:

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

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

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