我想使用manifestclasspath
Ant任务。我有一个非常大的build.xml文件,其中包含一些导入的其他构建文件,当我运行它时,我得到了这个:
build.xml:1289: The following error occurred while executing this line:
build.xml:165: Property 'some.property' already set!
我确信此属性仅在manifestclasspath
任务中定义。这是我的代码:
<manifestclasspath property="some.property" jarfile="some.jar">
<classpath refid="some.classpath"/>
</manifestclasspath>
此代码位于<project>
内。
我做错了什么?有没有办法添加像condition
这样的东西来设置属性只有它尚未设置?如果有其他方法,我不想使用Ant Contrib的if
之类的自定义Ant任务。
答案 0 :(得分:1)
Antcall打开一个新的项目范围,但默认情况下,当前项目的所有属性都将在新项目中可用。如果你使用了像
这样的东西<antcall target="whatever">
<param name="some.property" value="somevalue"/>
</antcall>
在调用项目中,$ {some.property}也已经设置并且不会被覆盖,因为设置的属性一旦设置就是不可变的。 或者,您可以将inheritAll属性设置为false,并且只将“user”属性(在命令行上传递的属性为-Dproperty = value)传递给新项目。 因此,当$ {some.property}不是用户属性时,请使用inheritAll =“false”并完成。
顺便说一句。最好通过depends =“...”属性使用目标之间的依赖关系而不是使用antcall,因为它打开了一个新的项目范围,并且在新项目中设置的属性将不会返回到调用目标,因为它存在于另一个项目范围..
关注代码段后,请注意区别,首先不要使用inheritAll属性
<project default="foo">
<target name="foo">
<property name="name" value="value1" />
<antcall target="bar"/>
</target>
<target name="bar">
<property name="name" value="value2" />
<echo>$${name} = ${name}</echo>
</target>
</project>
输出:
[echo] ${name} = value1
使用inheritAll = false
<project default="foo">
<target name="foo">
<property name="name" value="value1" />
<antcall target="bar" inheritAll="false" />
</target>
<target name="bar">
<property name="name" value="value2" />
<echo>$${name} = ${name}</echo>
</target>
</project>
输出:
[echo] ${name} = value2
antcall的一些经验法则,它很少被用于充分理由:
1.它打开一个新的项目范围(启动一个新的'ant -buildfile yourfile.xml yourtarget')所以它使用更多的内存,减慢你的构建
2.也会调用被叫目标的依赖目标!
3.属性不会传递回调用目标
在某些情况下,当调用相同的“独立”目标(没有目标的目标)时,可以使用不同的参数进行重用。通常,macrodef或scriptdef用于此目的。所以,在使用antcall之前要三思而后行,这也会给你的脚本带来多余的复杂性,因为它对正常流程起作用了。
使用依赖图而不是antcall来回答评论中的问题 你有一些目标,它包含所有条件并设置适当的属性,可以通过if和unless属性来评估目标,以控制进一步的流量
<project default="main">
<target name="some.target">
<echo>starting..</echo>
</target>
<!-- checking requirements.. -->
<target name="this.target">
<condition property="windowsbuild">
<os family="windows"/>
</condition>
<condition property="windowsbuild">
<os family="unix"/>
</condition>
<!-- ... -->
</target>
<!-- alternatively
<target name="yet.another.target" depends="this.target" if="unixbuild">
-->
<target name="another.target" depends="this.target" unless="windowsbuild">
<!-- your unixspecific stuff goes here .. -->
</target>
<!-- alternatively
<target name="yet.another.target" depends="this.target" if="windowsbuild">
-->
<target name="yet.another.target" depends="this.target" unless="unixbuild">
<!-- your windowspecific stuff goes here .. -->
</target>