2009-04-15 70 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>,所以我认为这对我来说已经足够好了。