Runtime.getRuntime().exec常见问题
今天搞了一天,JAVA调用一个PERL程序,得不得就退不出,千试万试,LOG精细到逐行,知道在哪停住了,但打死不知道为什么。
后来吃个饭都放弃了,居然又找到答案,要没看到它,那真以为里面有鬼了。
大概原因是,调用Runtime.getRuntime().exec后,如果不及时捕捉进程的输出,会导致JAVA挂住,看似被调用进程没退出。所以,解决办法是,启动进程后,再启动两个JAVA线程及时的把被调用进程的输出截获。
一下子,整个世界清爽多了。。。多谢这么仁兄,下面转一下:
转自:http://pudding.sharera.com/blog/BlogTopic/31232.htm
碰到一个项目需要从Java中运行Perl程序,这个Perl程序调用客户的Webservice,每次发送一个请求,接受一个响应。Java程序中包含多个请求,需要多次调用Perl程序,并且接受和解析响应(这个烂设计可不是我干的,我实在不明白强大的Java Web Service为什么要弄成这样,不过客户是老大)。使用JavaRuntime的exec()方法,发现运行一段时间后,进程就被挂起了(之前的响应完全正确)。于是分析原因,发现我在运行exec()方法后,立刻执行了Process的waitFor()方法,这里出了问题。在网上找到一篇文章讲述这个问题:
地址:http://brian.pontarelli.com/2005/11/11/java-runtime-exec-can-hang/
November 11, 2005 on 4:40 pm | In Java |
Thenext version of Savant is going to focus heavily on the stand-aloneruntime and support for dialects and plugins. Supporting all that islargely handled by using a simple executor framework I wrote aroundJava 1.4 and lower’s Runtime.exec method. A few things to keep in mindwhen using this:
可以看出:
永远要在调用waitFor()方法之前读取数据流 永远要先从标准错误流中读取,然后再读取标准输出流于是将waitFor()方法放在读取数据流后调用,目前没有发现什么问题。
正好解决了我心中的疑问,非常感谢!
我们的程序一开始就是exec完了接着waitFor(),但bat文件执行不完整:
Process proc = Runtime.getRuntime().exec(cmd);
??????????????? proc.waitFor();
后面的build中在waitFor()之前读取了数据流,bat文件就可以完整执行了:
Process proc = Runtime.getRuntime().exec(cmd);
?????StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");???????????
???????????????? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Output");
???????????????? errorGobbler.start();
???????????????? outputGobbler.start();
?????proc.waitFor();
class StreamGobbler extends Thread {
?InputStream is;
?String type;
?StreamGobbler(InputStream is, String type) {
??this.is = is;
??this.type = type;
?}
?public void run() {
??try {
???InputStreamReader isr = new InputStreamReader(is);
???BufferedReader br = new BufferedReader(isr);
???String line = null;
???while ((line = br.readLine()) != null) {
????if (type.equals("Error"))
?????LogManager.logError(line);
????else
?????LogManager.logDebug(line);
???}
??} catch (IOException ioe) {
???ioe.printStackTrace();
??}
?}
}
TestPrint.bat:
echo P1=%1? >D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
echo P2=%2 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
echo P3=%3 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
echo P4=%4 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
echo P5=%5 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
echo P6=%6 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
Bad_TestPrint.log:
P1=C:"xPression"CompuSet"output"MartyTestOut1.afp?
P2=Literal1
P3="Rick Skinner"
P4=Parameter3
Good_TestPrint.log
P1=C:"xPression"CompuSet"output"MartyTestOut1.afp?
P2=Literal1
P3="Rick Skinner"
P4=Parameter3
P5=Parameter4
P6=Parameter5