9

コマンドラインから ant を実行して失敗すると、ゼロ以外の終了ステータスが返されます (UNIX では $?、Windows では %ERRORLEVEL%)。しかし、(ProcessBuilder を介して) ant を実行している Java プログラムがあり、ant が失敗すると、Windows では終了ステータスを取得できません。

この単純な ant テスト ファイルでこれを確認しました。

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

UNIX では、ant を実行すると失敗メッセージが出力され、$? がエコーされます。Windows では、ant または ant.bat を実行すると失敗メッセージが出力され、後で %ERRORLEVEL% をエコーすると 1 が出力されます。

ここで、以下のテスト プログラムを使用します。 UNIX では、java Run ant は失敗メッセージを出力し、$? 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;
    }
  }
}
4

8 に答える 8

7

私は単一のバッチファイルを作成することでこの問題を解決しました(上記よりもかなり良いですが、それでも神秘的です):

ファイルの内容myant.bat

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

重要なのは、の後にコードがまったくないことですcall

于 2010-10-21T11:51:45.857 に答える
2

私はこの問題を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.batこれで、ProcessJavaからを呼び出すことができ、正しい終了値を取得できます。

申し訳ありませんが、なぜこれが機能するのかは言えません。それは単に多くの試みの結果です。

于 2009-09-22T03:53:14.540 に答える
2

クイック パッチでは、ANT.BAT ファイルの最後に次を追加します。

exit /b %ANT_ERROR%

この問題は以前から存在し、最近修正されました。バグ 41039を参照してください。

ANT リリース 1.8.2 以降で使用できるようになっているはずです。

于 2010-12-16T10:32:26.090 に答える
2

もう 1 つの問題 - 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
)
于 2012-01-09T16:43:49.233 に答える
1

.bat ファイル経由で Ant を実行する必要がありますか? これは単なる Java プログラムです。Ant ランタイムを直接インスタンス化して実行することで、VM 内で実行できます。ant.bat の内部を見て、その Main クラスが何であるかを確認し、それを直接実行します。

于 2009-09-21T21:30:46.377 に答える
0

これは、Windows 上の古いバージョンの Ant の長年の問題です。バージョン 1.7.0 で修正されていると思います。

詳細についてはこのバグを参照し、対処方法についてはこのディスカッションを参照してください。

于 2009-09-21T21:39:34.250 に答える
0

私はこのスレッドにグーグルでアクセスし、tangens の回答が私の問題をほぼ解決したことを発見しましant.batた。TFS ビルド スクリプトから終了コードを取得する必要がありますが、TFS ビルドでさえ%ERRORLEVEL%見つからないことが示されました。

/Bただし、 from行を削除する必要がありexitます。そうしないと、常に終了コード 0 が表示されます。

于 2010-05-10T21:15:24.330 に答える
0

私は次のように置き換えるIF ERRORLEVEL 1ことを解決しましたIF %ERRORLEVEL% NEQ 0:

call ant

IF %ERRORLEVEL% NEQ 0 GOTO :build_error
于 2016-01-26T09:46:11.623 に答える