无法从java启动程序(使用ProcessBuilder)
我试图从java应用程序调用cleartool,但cleartool即使对于一个简单的“-version”参数也会挂起。运行cleardiff而不是cleartool工作得很好,因此显然cleartool程序有一些特定的功能(我认为这与它的交互功能有关) 以下程序无法从java启动程序(使用ProcessBuilder),java,exec,Java,Exec,我试图从java应用程序调用cleartool,但cleartool即使对于一个简单的“-version”参数也会挂起。运行cleardiff而不是cleartool工作得很好,因此显然cleartool程序有一些特定的功能(我认为这与它的交互功能有关) 以下程序 import java.io.*; import java.util.*; public class ExecTesting extends Thread { private List<String> comm
import java.io.*;
import java.util.*;
public class ExecTesting extends Thread {
private List<String> command = new ArrayList<String>();
public ExecTesting (List<String> command) {
super();
this.command = command;
}
private void print(String s) {
System.out.println(s);
}
@Override
public void run() {
Process process;
OutputStream stdin;
InputStream stdout;
InputStream stderr;
String line;
try {
String commandString = joinList(command, " ");
print("Executing: " + commandString);
// runtime.exec has several issues (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1)
// better to use ProcessBuilder (http://java.sun.com/developer/JDCTechTips/2005/tt0727.html#2)
//process = Runtime.getRuntime().exec(commandString);
process = new ProcessBuilder(command).start();
// it fails in both cases though
stdin = process.getOutputStream();
stdout = process.getInputStream();
stderr = process.getErrorStream();
BufferedReader bufferedStderr = new BufferedReader(new InputStreamReader(stderr));
while ((line = bufferedStderr.readLine()) != null) {
print("stderr: " + line);
}
bufferedStderr.close();
BufferedReader bufferedStdout = new BufferedReader(new InputStreamReader(stdout));
while ((line = bufferedStdout.readLine()) != null) {
print("stdout: " + line);
}
bufferedStdout.close();
stdin.close();
stdout.close();
stderr.close();
process.waitFor();
print("Execution finished, exit code " + process.exitValue());
process.destroy();
} catch (IOException e) {
print("IOException: " +e.getStackTrace());
} catch (InterruptedException e) {
print("InterruptedException: " + e.getStackTrace());
}
}
/* assumes a list with at least one element */
private static String joinList(List<String> list, String glue) {
Iterator<String> i = list.iterator();
String ret = i.next();
while (i.hasNext()) {
ret += glue + i.next();
}
return ret;
}
public static void main(String[] args) {
ArrayList<String> cmd1 = new ArrayList<String>();
cmd1.add("c:\\Program Files\\Rational\\ClearCase\\bin\\cleardiff.exe");
cmd1.add("-version");
ExecTesting et1 = new ExecTesting(cmd1);
et1.start();
ArrayList<String> cmd2 = new ArrayList<String>();
//cmd2.add("c:\\Program Files\\Rational\\ClearCase\\bin\\cleardiff.exe");
cmd2.add("c:\\Program Files\\Rational\\ClearCase\\bin\\cleartool.exe");
cmd2.add("-version");
ExecTesting et2 = new ExecTesting(cmd2);
et2.start();
et1 = new ExecTesting(cmd1);
et1.start();
}
}
挂起cleartool命令的执行。如果改为将cmd2更改为cleardiff,则输出符合预期
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0
问题:有人知道cleartool为什么挂起以及如何修复吗?您应该在单独的线程中使用stdout和stderr,否则您将遇到阻塞行为
我怀疑这就是在这个实例中发生的事情(它与cleartool/cleardiff无关,只是它们正在输出stdout/err)。有关更多信息,请参阅。在开始等待终止之前,您似乎关闭了I/O流。您还可以按顺序读取stderr和stdout。但是,由于应用程序没有打印错误,并且您没有进入读取标准输出的阶段,所以对标准输出的读取会被阻塞。这个僵局 您可以通过
ProcessBuilder.redirectErrorStream()
加入stderr和stdout,然后只需读取stdout即可
您的示例在某些情况下有效,因为当您在stderr上被阻塞时,stdout上的应用程序响应不会达到通信缓冲区的大小。当应用程序退出时,stderr循环退出,stdout的循环能够重新释放该缓冲区的内容
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
Executing: [c:\Program Files\Rational\ClearCase\bin\cleardiff.exe, -version]
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0
stdout: cleardiff 2003.06.10+ (Tue Jul 13 14:02:05 2004)
Execution finished, exit code 0