java 为什么 ant.bat 以编程方式运行时不返回错误状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1456979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does ant.bat not return an error status when run programmatically?
提问by skiphoppy
When I run ant from the command-line, if I get a failure, I get a non-zero exit status ($? on UNIX, %ERRORLEVEL% on Windows). But we have a Java program which is running ant (through ProcessBuilder), and when ant fails, on Windows we cannot get the exit status.
当我从命令行运行 ant 时,如果失败,我会得到一个非零退出状态($? 在 UNIX 上,%ERRORLEVEL% 在 Windows 上)。但是我们有一个运行 ant 的 Java 程序(通过 ProcessBuilder),当 ant 失败时,在 Windows 上我们无法获得退出状态。
I just verified this with this simple ant test file:
我刚刚用这个简单的蚂蚁测试文件验证了这一点:
<project name="x" default="a">
<target name="a">
<fail/>
</target>
</project>
On UNIX, running ant prints a failure message, and echoing $? afterward prints 1. On Windows, running ant or ant.bat prints a failure message, and echoing %ERRORLEVEL% afterward prints 1.
在 UNIX 上,运行 ant 会打印一条失败消息,并回显 $? 之后打印 1。在 Windows 上,运行 ant 或 ant.bat 打印失败消息,然后回显 %ERRORLEVEL% 打印 1。
Now, using the test program below: On UNIX, java Run ant prints a failure message, and echoing $? afterward prints 1. On Windows, java Run ant can't find a program named ant to run, but java Run ant.bat prints a failure message, yet echoing %ERRORLEVEL% afterward prints 0. What gives?
现在,使用下面的测试程序: 在 UNIX 上,java Run ant 打印失败消息,并回显 $? 之后打印 1. 在 Windows 上,java Run ant 找不到名为 ant 的程序来运行,但 java Run ant.bat 打印失败消息,但随后回显 %ERRORLEVEL% 打印0。是什么赋予了?
We're relying on being able to check the exit status after running ant. We were, anyway. Why can't we rely on this, programmatically?
我们依赖于能够在运行 ant 后检查退出状态。无论如何,我们是。为什么我们不能以编程方式依赖它?
Test program:
测试程序:
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;
}
}
}
回答by Steve Powell
I solved this problem by creating a singlebatch file (quite a bit nicer than the above but still mysterious):
我通过创建一个解决了这个问题一个批处理文件(相当多的更好比上述但仍然神秘的):
Content of file myant.bat:
文件内容myant.bat:
@echo off
rem RunAnt simply calls ant -- correctly returns errorlevel for callers
call ant.bat %*
crucially, without any code whatsoever after the call.
至关重要的是,在call.
回答by Chau Chee Yang
回答by Don
Another issue - if you call ANT within a BAT file and you are interested in saving the errorlevel value, you must keep the call out of an if/else block.
另一个问题 - 如果您在 BAT 文件中调用 ANT 并且您有兴趣保存错误级别值,则必须将调用保留在 if/else 块之外。
For example, this won't work (...in the middle of some routine):
例如,这不起作用(...在某些例程中):
if "%DUMP_ARGS%"=="no" (
call ant %ANT_TARGETS%
set ANT_RETURN=%errorlevel%
)
You must break out the call as follows (...placed outside that routine):
您必须按如下方式中断调用(...放置在该例程之外):
:call_ant
call ant %ANT_TARGETS%
set ANT_RETURN=%errorlevel%
goto :eof
(...in the middle of some routine)
(......在一些例行公事的中间)
if "%DUMP_ARGS%"=="no" (
call :call_ant
)
回答by tangens
I solved this problem by creating two extra batch files (not very nice, but it works):
我通过创建两个额外的批处理文件解决了这个问题(不是很好,但它有效):
Content of file myant.bat:
文件内容myant.bat:
call ant2.bat %*
Content of file ant2.bat:
文件内容ant2.bat:
call ant.bat %*
if errorlevel 1 (goto ERROR_EXIT)
exit /B 0
:ERROR_EXIT
exit /B 1
Now I can call myant.batas a Processfrom java and I get the correct exit value.
现在我可以从 java调用myant.batas aProcess并获得正确的退出值。
Sorry, I cannot say whythis works. It's simply the result of a many many tries.
抱歉,我不能说为什么会这样。这只是多次尝试的结果。
回答by skaffman
Do you need to run Ant via its .bat file? It's just a java program, you could just execute in inside the VM by directly instantiating and executing the Ant runtime. Have a look inside ant.bat, see what its Main class is, and execute it directly.
您是否需要通过其 .bat 文件运行 Ant?它只是一个java程序,您可以通过直接实例化和执行Ant运行时在VM内部执行。看看ant.bat里面,看看它的Main类是什么,直接执行。
回答by Rich Seller
This is a long-standing issue for older versions of Ant on Windows. I believe it has been fixed in version 1.7.0.
对于 Windows 上的旧版 Ant,这是一个长期存在的问题。我相信它已在 1.7.0 版中修复。
See this bugfor details and this discussionfor an approach to address it.
回答by Sapience
I googled to this thread and find tangens' answer almost solved my problem: the exit coded are always 0 on Windows from ant.bat, even when I intentionally failed an ant build; I need to get the exit code from a TFS build script, and it showed that even the %ERRORLEVEL%can't be found in TFS build.
我用谷歌搜索了这个线程,发现 tangens 的答案几乎解决了我的问题:退出代码在 Windows 上始终为 0 ant.bat,即使我故意使 ant 构建失败;我需要从 TFS 构建脚本中获取退出代码,它表明即使%ERRORLEVEL%在 TFS 构建中也找不到。
However, I have to remove the /Bfrom exitlines, otherwise, it still always shows me exit code 0.
但是,我必须删除/Bfromexit行,否则,它仍然总是显示退出代码 0。
回答by kkk
i solved replacing IF ERRORLEVEL 1with IF %ERRORLEVEL% NEQ 0:
我解决了替换IF ERRORLEVEL 1为IF %ERRORLEVEL% NEQ 0:
call ant
IF %ERRORLEVEL% NEQ 0 GOTO :build_error

