Почему ant.bat не возвращает статус ошибки при программном запуске? - PullRequest
9 голосов
/ 22 сентября 2009

Когда я запускаю ant из командной строки, если я получаю ошибку, я получаю ненулевой статус выхода ($? В UNIX,% ERRORLEVEL% в Windows). Но у нас есть Java-программа, которая запускает ant (через ProcessBuilder), и когда ant не работает, в Windows мы не можем получить статус выхода.

Я только что подтвердил это с помощью простого файла теста для муравьев:

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

Ответы [ 8 ]

6 голосов
/ 21 октября 2010

Я решил эту проблему, создав одиночный командный файл (немного лучше, чем выше, но все еще загадочный):

Содержимое файла myant.bat:

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

крайне важно, без кода вообще после call.

2 голосов
/ 09 января 2012

Другая проблема - если вы вызываете ANT в BAT-файле и заинтересованы в сохранении значения уровня ошибки, вы должны держать вызов вне блока 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
)
2 голосов
/ 16 декабря 2010

Быстрый патч добавляет в конец файла ANT.BAT следующее:

exit /b %ANT_ERROR%

Эта проблема давно существует и исправлена ​​в последнее время. См. Ошибка 41039 .

Он должен быть готов к выпуску ANT 1.8.2 или новее.

2 голосов
/ 22 сентября 2009

Я решил эту проблему, создав два дополнительных пакетных файла (не очень хорошо, но это работает):

Содержимое файла 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.bat как Process из Java и получить правильное значение выхода.

Извините, я не могу сказать , почему это работает. Это просто результат многих попыток.

1 голос
/ 22 сентября 2009

Вам нужно запустить Ant через его файл .bat? Это просто Java-программа, вы можете просто выполнить ее внутри виртуальной машины, непосредственно создав и запустив среду выполнения Ant. Загляните внутрь ant.bat, посмотрите, каков его класс Main, и выполните его напрямую.

0 голосов
/ 26 января 2016

я решил заменить IF ERRORLEVEL 1 на IF %ERRORLEVEL% NEQ 0:

call ant

IF %ERRORLEVEL% NEQ 0 GOTO :build_error
0 голосов
/ 11 мая 2010

Я погуглил эту ветку и нашел, что ответ тангенса почти решил мою проблему: закодированный выход всегда равен 0 на Windows с ant.bat, даже когда я намеренно провалил сборку муравья; Мне нужно получить код завершения из сценария сборки TFS, и он показал, что даже %ERRORLEVEL% не может быть найден в сборке TFS.

Однако я должен удалить /B из exit строк, в противном случае он всегда показывает мне код выхода 0.

0 голосов
/ 22 сентября 2009

Это давняя проблема для старых версий Ant в Windows. Я считаю, что это было исправлено в версии 1.7.0.

См. эту ошибку для деталей и это обсуждение для подхода к ее устранению.

...