代码之家  ›  专栏  ›  技术社区  ›  ngn

Ant中的类路径验证

  •  2
  • ngn  · 技术社区  · 15 年前

    我有一个 <path id="..."> 在我的 build.xml . 在调用编译器之前,我想验证类路径上的每个jar/目录是否存在,并打印一个包含缺少的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);
                }
            }
        }
    }
    
    3 回复  |  直到 11 年前
        1
  •  1
  •   VonC    15 年前

    我会说,一个定制的蚂蚁任务可能是有序的,有点像 org.netbeans.modules.bpel.project.anttasks.ValidateBPELProjectTask 在A中完成 pre-dist '此目标 build.xml .

    注: ValidateBPELProjectTask ant task 比通常的自定义任务要复杂一点:它需要有自己的类路径才能运行(类路径最初没有传递给build.xml)。
    由于无法修改当前Ant任务类加载器的类路径,因此validateppelprojecttask定义了一个新的 AntClassLoader 和电话 setContextClassLoader() .

    不过,您不需要这样的机制:您只需将目录列表作为参数传递给您的任务即可。

        2
  •  2
  •   Lee Meador    11 年前

    这将检查类路径中的每个文件或文件夹是否存在。如果其中一个没有,那么显示第一个找不到的名字的构建将失败。

    <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

    这将需要加载ant contrib jar并连接其中的所有目标:

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

    应该存在一个 <for> 允许设置选项以继续浏览所有路径元素并只在结尾显示错误的任务。我发现我的Eclipse版本 <前述的; 已经在课堂上了,所以我觉得这对我来说已经足够好了。

        3
  •  1
  •   martin clayton egrunin    13 年前

    在Ant脚本中,我没有找到很多使用默认任务迭代路径的方法。如果您在一台具有类似Unix的shell的机器上进行构建,那么您可以调用shell来检查类路径元素。

    调用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!"
    

    如果希望生成失败,可以设置 应用 如果报告了错误(本例中缺少文件/目录),任务将失败,然后在打印警告后修改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>