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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:36:38  来源:igfitidea点击:

Why does ant.bat not return an error status when run programmatically?

javaantexecfork

提问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

A quick patch is adding the following at the end of ANT.BAT file:

一个快速补丁是在 ANT.BAT 文件的末尾添加以下内容:

exit /b %ANT_ERROR%

This problem has long existed and fixed recently. Refer to Bug 41039.

这个问题由来已久,最近已修复。请参阅错误 41039

It should be ready in ANT release 1.8.2 or later.

它应该在 ANT 版本 1.8.2 或更高版本中准备就绪。

回答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 1IF %ERRORLEVEL% NEQ 0

call ant

IF %ERRORLEVEL% NEQ 0 GOTO :build_error