ski*_*ppy 9 java ant fork exec
当我从命令行运行ant时,如果出现故障,我会得到一个非零退出状态(UNIX上的$ ?, Windows上的%ERRORLEVEL%).但我们有一个运行ant的Java程序(通过ProcessBuilder),当ant失败时,在Windows上我们无法获得退出状态.
我刚用这个简单的ant测试文件验证了这个:
<project name="x" default="a">
<target name="a">
<fail/>
</target>
</project>
Run Code Online (Sandbox Code Playgroud)
在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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我通过创建一个解决了这个问题一个批处理文件(颇有几分比上述但仍然神秘更好):
文件内容myant.bat:
@echo off
rem RunAnt simply calls ant -- correctly returns errorlevel for callers
call ant.bat %*
Run Code Online (Sandbox Code Playgroud)
至关重要的是,没有任何代码call.
您需要通过 Ant 的 .bat 文件运行它吗?它只是一个java程序,您可以通过直接实例化并执行Ant运行时来在VM内部执行。看一下ant.bat里面,看看它的Main类是什么,直接执行。