2009-09-21 80 views
9

當我從命令行運行ant時,如果出現故障,我會得到一個非零的退出狀態(UNIX上爲$ ?, Windows上爲%ERRORLEVEL%)。但是我們有一個正在運行ant的Java程序(通過ProcessBuilder),當螞蟻失敗時,在Windows上我們無法獲得退出狀態。爲什麼在編程運行時ant.bat不會返回錯誤狀態?

我只是用這個簡單的螞蟻測試文件驗證了這一點:

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

在UNIX上,運行ant打印失敗的消息,並呼應$?隨後打印1. 在Windows上,運行ant或ant.bat打印失敗消息,並呼應%ERRORLEVEL%之後Prints立即1.

,使用下面的測試程序: 在UNIX上,Java運行Ant打印出故障消息,並回顯$?之後打印1. 在Windows上,java運行ant無法找到一個名爲ant的程序來運行,但是java運行ant.bat會打印一條失敗消息,然後回顯%ERRORLEVEL%打印。是什麼賦予了?

我們依靠運行螞蟻后能夠檢查退出狀態。無論如何,我們是。爲什麼我們不能依靠這個,以編程方式?

測試程序:

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

回答

1

你需要通過它的.bat文件運行Ant?它只是一個Java程序,您可以直接實例化並執行Ant運行時,在VM內執行。看一看ant.bat,看看它的Main類是什麼,然後直接執行它。

+0

ant.bat比較複雜,直接運行java程序相當複雜。我看到了在ant腳本中執行ant.bat的相同問題(不,請不要問)。我看不到ant.bat錯誤級別。我不想將ant2.bat傳遞給我的構建者環境,但是如果必須的話,我會這樣做。 有誰知道*爲什麼*這個工程? PS:什麼是此評論的格式標記? – 2010-10-20 17:34:46

0

這是Windows上舊版Ant的一個長期問題。我相信它已在1.7.0版本中得到修復。

查看this bug的詳細信息和this discussion的方法來解決它。

+1

我在螞蟻1.7.1。我只是試着運行完整的路徑,以確保我沒有運行另一個版本的螞蟻。相同的行爲:從提示符運行時更正錯誤級別;從程序運行時錯誤級別不正確。 – skiphoppy 2009-09-22 13:53:54

2

我創建了兩個額外的批處理文件,解決了這個問題(不是很漂亮,但它的工作原理):

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

call ant2.bat %* 

內容:文件myant.bat

內容

現在我可以從java調用myant.bat作爲Process,我得到正確的退出值。

對不起,我不能說爲什麼這個工程。這只是許多嘗試的結果。

0

我用google搜索了這個帖子,發現tangens的回答幾乎解決了我的問題:即使我故意螞蟻構建失敗,在Windows上從ant.bat開始編碼的退出總是0;我需要從TFS構建腳本獲取退出代碼,並且它表明即使在TFS構建中也找不到%ERRORLEVEL%

但是,我必須從exit行中刪除/B行,否則,它仍會始終顯示我退出代碼0。

6

我通過創建一個批處理文件,解決了這個問題(頗有幾分比以上,但仍然神祕爽):

文件myant.bat的內容:

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

關鍵的是,沒有任何代碼無論在call之後。

+0

+1有同樣的問題試圖從psake調用螞蟻。這解決了我的問題。 – 2010-12-14 19:11:29

2

快速補丁將在ANT.BAT文件的末尾以下內容:

exit /b %ANT_ERROR% 

這個問題存在已久,並固定最近。請參閱Bug 41039

它應該在ANT版本1.8.2或更高版本中準備好。

2

另一個問題 - 如果您在BAT文件中調用ANT並且有興趣保存錯誤級別值,則必須將該調用保留在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 
) 
0

我解決了用01代替:

call ant 

IF %ERRORLEVEL% NEQ 0 GOTO :build_error 
相關問題