Ant 清单类路径:属性已设置
我想使用 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>
此代码位于
内部。
我做错了什么?有没有办法添加类似 condition
的内容来设置属性(仅当属性尚未设置时)?如果有其他方法,我不想使用自定义 Ant 任务,例如 Ant Contrib 的 if
。
I want to use manifestclasspath
Ant task. I have a very large build.xml file with a couple of imported other build files and when I run it I get this:
build.xml:1289: The following error occurred while executing this line:
build.xml:165: Property 'some.property' already set!
I am sure that this property is defined only in manifestclasspath
task. Here is my code:
<manifestclasspath property="some.property" jarfile="some.jar">
<classpath refid="some.classpath"/>
</manifestclasspath>
This code is located inside of <project>
.
What am I doing wrong? Is there a way to add something like condition
to set property only if it is not already set? I don't want to use custom Ant tasks such as Ant Contrib's if
if there is other way around.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Antcall 打开一个新的项目范围,但默认情况下,当前项目的所有属性都将在新项目中可用。另外,如果您在调用项目中使用了类似 = 的内容
,那么 ${some.property} 也已经设置并且不会被覆盖,因为设置后的属性在 ant 中是不可变的。
或者,您可以将继承所有属性设置为 false,并且只有“用户”属性(通过 -Dproperty=value 在命令行上传递的属性)将传递到新项目。
因此,当 ${some.property} 不是用户属性时,请使用inheritAll="false" 就完成了。
顺便提一句。通过depends =“...”属性使用目标之间的依赖关系比使用antcall更好,因为它打开一个新的项目范围,并且新项目中设置的属性不会返回到调用目标,因为它位于另一个项目中项目范围..
在代码片段之后,请注意差异,首先没有继承All属性
输出:
第二个有inheritAll = false
输出:
antcall的一些经验法则,它很少被使用是有充分理由的:
1.它打开一个新的项目范围(启动一个新的“ant -buildfile yourfile.xml yourtarget”)
因此它使用更多内存,减慢构建速度
2. 被调用目标的依赖目标也将被调用!
3. 属性不会传递回调用目标
在某些情况下,使用不同的参数调用相同的“独立”目标(没有依赖的目标的目标)以供重用时可能没问题。通常,macrodef 或 scriptdef 用于此目的。因此,在使用 antcall 之前请三思而行,这也会给您的脚本带来多余的复杂性,因为它违背了正常流程。
在评论中回答您的问题,使用依赖关系图而不是 antcall
您有一些目标,它包含所有条件并设置适当的属性,目标可以通过 if 和 except 属性来评估这些属性来控制进一步的流程
Antcall opens a new project scope, but by default, all of the properties of the current project will be available in the new project. Also if you used something like =
in the calling project then ${some.property} is also already set and won't be overwritten, as properties once set are immutable in ant by design.
Alternatively, you may set the inheritAll attribute to false and only "user" properties (those passed on the command-line with -Dproperty=value) will be passed to the new project.
So, when ${some.property} ain't no user property, then use inheritAll="false" and you're done.
btw. it's better to use a dependency between targets via depends="..." attribute than to use antcall, because it opens a new project scope and properties set in the new project won't get back to the calling target because it lives in another project scope..
Following a snippet, note the difference, first without inheritAll attribute
output :
second with inheritAll=false
output :
some rules of thumb for antcall, it's rarely used for good reasons :
1. it opens a new project scope (starting a new 'ant -buildfile yourfile.xml yourtarget')
so it uses more memory, slowing down your build
2. depending targets of the called target will be called also !
3. properties don't get passed back to the calling target
In some cases it might be ok when calling the same 'standalone' target (a target that has no target it depends on) with different params for reuse. Normally macrodef or scriptdef are used for that purpose. So, think twice before using antcall which also puts superfluous complexity to your scripts, because it works against the normal flow.
Answer to your question in the comment, using a dependency graph instead of antcall
you have some target that holds all conditions and sets the appropriate properties which may be evaluated by targets via if and unless attributes to control the further flow