使用ant读取属性文件中的属性不遵守顺序

时间:2012-02-03 08:12:48

标签: file ant properties task

使用ant不尊重顺序读取属性文件中的属性。

订单不受尊重:

示例:

<property file="build.properties" prefix="prefix."/>
<propertyselector property="cases" match="prefix.project\.(.*)" select="\1"/>
<for list="${cases}" param="pr">
<sequential>
<echo message="Project: @{pr} Version: ${prefix.project.@{pr}}"/>
</sequential>
</for>

使用:

build.properties

project.1 = 1.2.3
project.8 = 5.9.4
project.4 = 3.5.0

得到:

 Project: 8 Version 5.9.4
 Project: 1 Version 1.2.3
 Project: 4 Version 3.5.0

(结果似乎随机改变) 我必须按照它们在build.properties文件中出现的顺序构建它们吗?

3 个答案:

答案 0 :(得分:2)

正在以正确的顺序读取属性文件。您可以通过简单地放入重复的属性并查看哪个属性被定义来测试它。这是build.properties

dup.prop = foo
dup.prop = bar

这是我的Ant脚本:

<project>
    <property file="build.properties"/>
    <echo>Dup.prop is set to "${dup.prop}".</echo>
</project>

运行这个,我会得到:

Dup.prop is set to "foo".

这是因为 foo 的值首先在build.properies中定义,一旦定义了属性,就无法(轻松)更改。

您要做的是按照定义的顺序访问属性。这不能保证,因为属性存储在散列中。

您提到子项目,这些子项目必须按特定顺序构建。不幸的是,由于您没有给我们提供实际问题的概述以及项目和子项目的一些示例构建脚本,因此很难准确说明问题所在。

首先,Ant是构建矩阵语言,这意味着它具有依赖关系层次结构。开发人员面临的最大问题是试图强制构建矩阵语言以特定顺序执行。您应该在build.xml文件中指定依赖关系层次结构(并且它们越少,Ant就越容易正确)。

如果子项目“B”依赖于子项目“A”中的jar文件,那么它应该在子项目“B”的Ant脚本中依赖于子项目“A”jar构建。 / p>

<project name="proj-b"/>
    ...
    <target name="build-jar"
        depends="test.if.jar.exists"
        unless="jar.exist">
        <ant directory="${proj.a.dir}"
           target="build.depend.jar"/>
    </target>

    <target name="test.if.jar.exists">
        <condition property="jar.exists">
           <available file="${proj.a.dir}/dist/${dend.jar.file}"/>
        </condition>
    </target>

    <target name="compile"
        depends="build-jar">
        ....
    </target>
    ...
</project>

在上面的build.xml for Project“B”中,我依赖于项目“A”构建的jar文件,然后才能编译Project“B”。因此,我的compile任务依赖于build-jar,它将构建目标“A”的jar文件。为了防止这个任务一遍又一遍地构建Project“A”的jar,我使用<condition>作为测试来查看这个jar是否存在。如果它已经存在,我不会重建jar。

在这种情况下:

  • 调用目标“编译”。该目标意识到它取决于Target“build-jar”。
  • 执行目标“编译”之前。首先调用目标“build-jar”。
  • 目标“build-jar”取决于Target“test.if.jar.exists”。
  • 在执行“build-jar”之前,它调用Target“test.if.jar.exists”
  • 在Target“test.if.jar.exists”中,如果jar已存在,则将设置属性jar.exists
  • 现在,Target“build-jar”处于活动状态,并查看是否设置了属性jar.exists。如果是,则目标不会执行。
  • 最后,控制返回到目标“编译”,然后执行。

这里我没有直接执行订单。相反,我只是有一个我指定的依赖层次结构,我让Ant弄明白该做什么。

如果依赖jar问题是一个大问题,您也可以查看Ivy。 Ivy允许您创建 Jar存储库。您的项目构建其他项目的jar依赖于可以从此存储库中获取所需的jar。这与Maven非常相似。实际上,使用Ivy的Ant可以使用Maven存储库。我们为我们的Ant项目使用Artifactory,一个本地Maven存储库管理器。

您还可以尝试<subant>任务,该任务允许您指定 buildpath ,这样您就可以在子项目之前说出构建子项目“A” B“。您可以在另一个可能依赖于客户的Ant XML文件中定义 buildpath ,然后使用<import>导入该项目的构建路径。

答案 1 :(得分:1)

事实上。 Java属性用java.util.Hashtable表示,并且您肯定知道,哈希表不保留顺序。你根本无法用属性文件做你想做的事。

如果您声明要按顺序构建的那些“项目”依次是Ant项目,您可能需要考虑将其任务移动到主构建文件,并使用正常的Ant依赖项简单地强制执行正确的构建顺序

答案 2 :(得分:0)

以下代码将有助于对propertyselector标记

生成的列表进行排序
<sortlist property="my.sorted.list" value="${my.list}"
             delimiter="," />
<echo message="${my.sorted.list}" />