Ant manifestclasspath:属性已设置

时间:2011-06-28 10:45:16

标签: ant classpath manifest

我想使用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任务。

1 个答案:

答案 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>