2009-04-15 109 views
2

我在我的build.xml中有<path id="...">。在調用編譯器之前,我想驗證類路徑上的每個jar /目錄是否存在,並打印出缺少的警告。有人知道現有的解決方案還是需要爲此編寫我自己的任務?螞蟻中的類路徑驗證


好吧,我決定去一個自定義的任務。這是在任何情況下,需要過這樣一件事:

import java.io.File; 
import java.util.Iterator; 

import org.apache.tools.ant.BuildException; 
import org.apache.tools.ant.Task; 
import org.apache.tools.ant.types.Reference; 
import org.apache.tools.ant.types.ResourceCollection; 
import org.apache.tools.ant.types.resources.Resources; 

public class CheckClasspathTask extends Task { 

    private Reference reference; 

    public CheckClasspathTask() { 
    } 

    public void setRefId(Reference reference) { 
     this.reference = reference; 
    } 

    public void execute() throws BuildException { 
     Resources resources = new Resources(); 
     resources.setProject(getProject()); 
     resources.add((ResourceCollection) reference.getReferencedObject()); 
     boolean isFirst = true; 
     for (Iterator i = resources.iterator(); i.hasNext();) { 
      String f = i.next().toString(); 
      if (!new File(f).exists()) { 
       if (isFirst) { 
        isFirst = false; 
        System.out.println("WARNING: The following entries on your classpath do not exist:"); 
       } 
       System.out.println(f); 
      } 
     } 
    } 
} 

回答

1

我要說的可能是一個定製Ant任務是爲了,有點像在這個build.xml的「pre-dist」目標完成的org.netbeans.modules.bpel.project.anttasks.ValidateBPELProjectTask

注意:ValidateBPELProjectTask ant task比通常的自定義任務要複雜一點:它需要有自己的類路徑來運行(最初,類路徑最初不會傳遞給build.xml)。
由於您無法修改當前ant任務類加載器的類路徑,因此ValidateBPELProjectTask會定義一個新的AntClassLoader並調用setContextClassLoader()

雖然您不需要這樣的機制:您可以將目錄列表作爲參數傳遞給您的任務。

+0

我似乎記得傳遞一個路徑對象到一個自定義任務很容易 - 我想這就是你的意思是「傳遞目錄列表」? – araqnid 2009-04-15 23:46:35

+0

@araqnid是的,這就是我的意思 – VonC 2009-04-16 10:25:46

1

我還沒有找到許多方法來使用默認任務迭代Ant腳本中的路徑。如果您在具有類UNIX的外殼的計算機上構建,則可以調用外殼來檢查類路徑元素。

當調用shell腳本時,可以使用apply task,但是當classpath元素不存在時我無法打印它。

讓我們假設你有以下的類路徑聲明:

<path id="your.classpath"> 
    <fileset dir="your.libs"/> 
    <pathelement location="/some/missing/dir"/> 
</path> 

,如果有任何缺少的元素這將報告,但並沒有告訴你哪些:

<apply executable="test" type="file" ignoremissing="false"> 
    <arg value="-e"/> 
    <srcfile/> 
    <path refid="build.classpath"/> 
</apply> 

你可以結合這用一個簡單的shell腳本,並通過更改executable屬性來獲取所需內容 - 假設您只想要一個大警告消息而不是構建失敗:

#!/bin/sh 

test -e "$1" || echo "WARNING: Classpath element $1 does not exist!" 

如果您希望構建失敗,可以將apply任務設置爲失敗,如果報告了錯誤(在這種情況下缺少文件/目錄),然後修改shell腳本以在返回非零退出代碼之後警告被打印。

另一種方法是使用exec task,只是執行一個腳本內聯:

<pathconvert property="classpath" refid="build.classpath" pathsep=":"/> 
<exec executable="sh"> 
    <arg value="-c"/> 
    <arg value="for f in `echo ${classpath} | tr ':' '\n'`; do test -e $f || echo WARNING: Classpath element $f  does not exist!; done"/> 
</exec> 
2

這將檢查在類路徑中的每個文件或文件夾是否存在。如果其中一個不這樣做,它將會失敗顯示第一個無法找到的名稱的構建。

<target name="check-classpath" depends="create-classpath"> 
    <pathconvert pathsep="," property="myclasspath" refid="compile.classpath"/> 
    <foreach list="${myclasspath}" param="file" target="check-file-or-folder-exists" /> 
</target> 

<target name="check-file-or-folder-exists"> 
    <fail message="Error: ${file} not found"> 
     <condition> 
     <not> 
      <available file="${file}" /> 
     </not> 
     </condition> 
    </fail> 
</target> 

注意<foreach>是螞蟻貢獻 - Ant Contribs clickable LINK

這將需要加載螞蟻contrib請罐和掛接在這一切的目標:

<taskdef resource="net/sf/antcontrib/antcontrib.properties"> 
    <classpath> 
     <pathelement location="${some.lib.dir}/ant-contrib-1.0b3.jar" /> 
    </classpath> 
</taskdef> 

有應該存在一個<for>任務,該任務將允許設置一個選項以繼續遍歷所有路徑元素,並僅在最後顯示錯誤。我發現我的Eclipse版本已經在類路徑中有<foreach>,所以我認爲這對我來說已經足夠好了。