4

我对和属性有这种奇怪的行为,ant我想知道你的想法。我不明白这个逻辑。这种行为可能很有用,但我想知道我是否可以依赖它或者这是否是一个错误。

如果没有所需名称的属性,则在扩展属性的右侧时,似乎 ant 正在应用前缀。这是SSCCE:

build.properties:

a=A
formula=${a}

构建.xml:

<project default="test">
    <target name="test">
        <property name="test.a" value="[test.a has been used instead of a, why? prefixValues is false]" />
        <property file="build.properties" prefix="test" prefixValues="false" />
        <echo>${test.formula}</echo>
    </target>
</project>

输出:

test:
    [echo] [test.a has been used instead of a, why? prefixValues is false]
BUILD SUCCESSFUL
Total time: 364 milliseconds

如您所见,test.formula 应该使用“a”而不是“test.a”,但从未定义过“a”。是这个原因吗?

4

4 回答 4

1

的确,这似乎很奇怪。在我看来,输出应该是${a}

我做了一些测试,我注意到:

如果您abuild.xml而不是build.properties: 中定义它会按预期工作。即具有以下内容build.xml

<project default="test">
<target name="test">
    <property name="a" value="A" />
    <property file="build.properties" prefix="test" prefixValues="false" />
    <echo>${test.formula}</echo>
</target>
</project>

和 build.properties

formula=${a}

输出是

A

但是,如果你改变prefixValues="true"输出是:

${a}

在我期待的时候:${test.a}

最后,如果您<property name="test.a" value="some value" />在 build.xml 中定义(始终使用prefixValues="true"):输出现在(如预期的那样)

some value

所以,我的结论:

  • 只要右侧使用的属性未在同一属性文件中定义,prefixValues 就可以正常工作。

  • 对于右侧使用并在同一属性文件中定义的属性,prefixValues 将被忽略。

于 2013-03-27T17:00:44.260 回答
1

看一下 Ant 代码,在属性相关的类中,在org.apache.tools.ant.property.ResolvePropertyMap类上:

public void resolveAllProperties(Map<String, Object> map, String prefix,
                                     boolean prefixValues) {
        // The map, prefix and prefixValues flag get used in the
        // getProperty callback
        this.map = map;
        this.prefix = prefix;
        this.prefixValues = prefixValues;

        for (String key : map.keySet()) {
            expandingLHS = true;
            Object result = getProperty(key);
            String value = result == null ? "" : result.toString();
            map.put(key, value);
        }

然后,在getProperty(String)方法(片段)中:

            // If the property we are looking up is a key in the map
            // (first call into this method from resolveAllProperties)
            // or we've been asked to prefix the value side (later
            // recursive calls via the GetProperty interface) the
            // prefix must be prepended when looking up the property
            // outside of the map.
            String fullKey = name;
            if (prefix != null && (expandingLHS || prefixValues)) {
                fullKey = prefix + name;
            }

因此,如您所见,如果属性文件中存在该属性,即使prefixValues为 false,它也会收到前缀。

于 2013-03-28T19:41:48.537 回答
0

我又进行了一些测试,可能会得到很多不同的结果。

检查来源后,我认为在通过文件添加属性时查找属性时存在错误。通过修改一些 ant 源代码,我可以让它工作。

最后,我决定用建议的补丁填写错误报告( https://issues.apache.org/bugzilla/show_bug.cgi?id=54769 )。

谢谢你们。

于 2013-03-30T12:28:01.773 回答
-1

这是因为属性是不可变的。一旦设置好,它们就会在构建的其余部分中被卡住。 查看 Ant 手册中的“属性”文档。 对于某些人来说,这实际上是一个问题,所以ant-contrib 的家伙们加入了一项新任务来模拟一个变量。

如果您像这样更改构建:

<project default="test">
    <target name="test">
        <property file="build.properties" prefix="test" prefixValues="false" />
        <property name="test.a" value="[test.a has been used instead of a, why? prefixValues is false]" />
        <echo>${test.formula}</echo>
    </target>
</project>

你在控制台上得到“A”。这是因为 test.a 和 test.formula 是在您对“test.a”的新(忽略)分配之前的第一次调用中定义的

于 2013-03-25T18:52:59.203 回答