碰到一个项目需要从Java中运行Perl程序,这个Perl程序调用客户的Web service,每次发送一个请求,接受一个响应。Java程序中包含多个请求,需要多次调用Perl程序,并且接受和解析响应(这个烂设计可不是我干的,我实在不明白强大的Java Web Service为什么要弄成这样,不过客户是老大)。使用Java Runtime的exec()方法,发现运行一段时间后,进程就被挂起了(之前的响应完全正确)。于是分析原因,发现我在运行exec()方法后,立刻执行了Process的waitFor()方法,这里出了问题。在网上找到一篇文章讲述这个问题: 地址:http://brian.pontarelli.com/2005/11/11/java-runtime-exec-can-hang/ Java Runtime exec can hangNovember 11, 2005 on 4:40 pm | In Java |The next version of Savant is going to focus heavily on the stand-alone runtime and support for dialects and plugins. Supporting all that is largely handled by using a simple executor framework I wrote around Java 1.4 and lower’s Runtime.exec method. A few things to keep in mind when using this:
|
正好解决了我心中的疑问,非常感谢!
我们的程序一开始就是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