当我从命令行运行 ant 时,如果失败,我会得到一个非零退出状态($? 在 UNIX 上,%ERRORLEVEL% 在 Windows 上)。但是我们有一个运行 ant 的 Java 程序(通过 ProcessBuilder),当 ant 失败时,在 Windows 上我们无法获得退出状态。
我刚刚用这个简单的 ant 测试文件验证了这一点:
<project name="x" default="a">
<target name="a">
<fail/>
</target>
</project>
在 UNIX 上,运行 ant 会打印一条失败消息,并回显 $? 之后打印 1。在 Windows 上,运行 ant 或 ant.bat 打印失败消息,然后回显 %ERRORLEVEL% 打印 1。
现在,使用下面的测试程序: 在 UNIX 上,java Run ant 打印一条失败消息,并回显 $? 之后打印 1. 在 Windows 上, java Run ant 找不到要运行的名为 ant 的程序,但 java Run ant.bat 打印失败消息,但回显 %ERRORLEVEL% 之后打印0。是什么赋予了?
我们依赖于能够在运行 ant 后检查退出状态。反正我们是。为什么我们不能以编程方式依赖它?
测试程序:
import java.io.*;
public class Run {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder(args);
Process p = pb.start();
ProcThread stdout = new ProcThread(p.getInputStream(), System.out);
ProcThread stderr = new ProcThread(p.getErrorStream(), System.err);
stdout.start();
stderr.start();
int errorLevel = p.waitFor();
stdout.join();
stderr.join();
IOException outE = stdout.getException();
if (outE != null)
throw(outE);
IOException errE = stdout.getException();
if (errE != null)
throw(errE);
System.exit(errorLevel);
}
static class ProcThread extends Thread {
BufferedReader input;
PrintStream out;
IOException ex;
ProcThread(InputStream is, PrintStream out) {
input = new BufferedReader(new InputStreamReader(is));
this.out = out;
}
@Override
public void run() {
String line;
try {
while ((line = input.readLine()) != null)
out.println(line);
} catch (IOException e) {
setException(e);
}
}
private void setException(IOException e) {
this.ex = e;
}
public IOException getException() {
return ex;
}
}
}