为什么编程方式运行时ant.bat不返回一个错误?(Why does ant.bat not ret

2019-08-08 14:22发布

当我在命令行运行ant,如果我失败了,我得到一个非零退出状态($?在UNIX,Windows上的%ERRORLEVEL%)。 但是,我们有正在运行的蚂蚁(通过的ProcessBuilder)的Java程序,当蚂蚁失败,在Windows上我们无法获得退出状态。

我只是验证了这本简单的蚂蚁测试文件:

<project name="x" default="a">
  <target name="a">
    <fail/>
  </target>
</project>

在UNIX上,运行ant打印失败的消息,并呼应$? 之后打印1.在Windows中,运行ant或ant.bat打印失败消息,并呼应%ERRORLEVEL%之后打印1。

现在,使用下面的测试程序:在UNIX上,Java运行蚂蚁打印失败的消息,并呼应$? 随后打印1.在Windows,Java运行蚂蚁无法找到一个程序名为ant运行,但Java运行ant.bat打印失败的消息,但呼应%ERRORLEVEL%之后打印0。 是什么赋予了?

我们依靠能够运行蚁后检查退出状态。 我们,反正。 为什么我们不能靠这个,编程?

测试程序:

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;
    }
  }
}

Answer 1:

我通过创建一个批处理文件(颇有几分比上面却依然神秘的更好)解决了这个问题:

文件的内容myant.bat

@echo off
rem RunAnt simply calls ant -- correctly returns errorlevel for callers
call ant.bat %*

关键的是,没有任何之后的任何代码call



Answer 2:

我通过创建两个额外的批处理文件,解决了这个问题(不是很漂亮,但它的工作原理):

文件的内容myant.bat

call ant2.bat %*

文件的内容ant2.bat

call ant.bat %*
if errorlevel 1 (goto ERROR_EXIT)
exit /B 0
:ERROR_EXIT
exit /B 1

现在,我可以叫myant.batProcess从Java和我得到正确的出口值。

对不起,我不能说为什么这个工程。 它只是一个很多很多尝试的结果。



Answer 3:

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

exit /b %ANT_ERROR%

这个问题存在已久,最近固定。 请参阅错误41039 。

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



Answer 4:

另一个问题 - 如果你一个BAT文件中调用Ant和你有兴趣节省ERRORLEVEL值,你必须保持通话出的if / else块。

例如,这是不行的(...在一些常规的中间):

if "%DUMP_ARGS%"=="no" (
   call ant %ANT_TARGETS%
   set ANT_RETURN=%errorlevel%
)

你必须打出来的电话如下(...放置在常规之外):

:call_ant
call ant %ANT_TARGETS%
set ANT_RETURN=%errorlevel%
goto :eof

(...在一些常规的中间)

if "%DUMP_ARGS%"=="no" (
    call :call_ant
)


Answer 5:

你需要通过它的.bat文件运行Ant? 这只是一个Java程序,你可以只通过直接实例化和执行的Ant运行时执行在虚拟机内。 看看里面ant.bat,看到它的主类是什么,直接执行它。



Answer 6:

这是在Windows旧版本的Ant的一个长期存在的问题。 我相信它已被固定在1.7.0版本。

请参阅此漏洞的详细信息,并讨论了一种方法来解决这个问题。



Answer 7:

我用Google搜索这个主题并找到tangens的回答几乎解决我的问题:退出编码始终为0在Windows上从ant.bat ,甚至当我故意失败的Ant构建; 我需要从TFS构建脚本获取退出代码,它表明,即使在%ERRORLEVEL%不能在TFS构建找到。

但是,我不得不删除/Bexit线,否则,它仍然总是显示我退出代码0。



Answer 8:

我解决更换IF ERRORLEVEL 1IF %ERRORLEVEL% NEQ 0

call ant

IF %ERRORLEVEL% NEQ 0 GOTO :build_error


文章来源: Why does ant.bat not return an error status when run programmatically?
标签: java ant exec fork