gpt4 book ai didi

java - macrodef 没有正确传达退出状态

转载 作者:行者123 更新时间:2023-11-30 08:18:33 25 4
gpt4 key购买 nike

我正在调用一个使用 macrodef 定义的 Ant 任务,但我发现 fail 任务的退出状态没有正确地传送到 shell。

以下是SSCCE:

Ant 文件:

<project>

<macrodef name="ff">
<sequential>
<fail message="some failure" status="3"/>
</sequential>
</macrodef>

<ff/>

</project>

调用:

$ ant 
Buildfile: /[...]/build.xml

BUILD FAILED
[...]build.xml:10: The following error occurred while executing this line:
[...]build.xml:5: some failure

Total time: 0 seconds

构建如预期的那样失败了;但退出状态不正确:

$ echo $?
1

Ant 以状态 1 而不是 3 退出。只有当 fail 任务被包裹在 macrodef 中时才会发生这种情况。

最佳答案

初步猜测可以从the documentation of the fail task获得关于 status 属性:

Exit using the specified status code; assuming the generated Exception is not caught, the JVM will exit with this status.

这正是使用 macrodef 时发生的情况:由 fail 任务抛出以退出构建的 BuildException捕获宏定义。最终吞下退出代码的 macrodef 抛出某种包装器异常

在 Debug模式下运行 Ant 时,您还可以从异常堆栈跟踪中看到这一点:

使用宏定义:

some failure
at org.apache.tools.ant.taskdefs.Exit.execute(Exit.java:164)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:398)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:390)
at org.apache.tools.ant.Target.performTasks(Target.java:411)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
at org.apache.tools.ant.Main.runBuild(Main.java:809)
at org.apache.tools.ant.Main.startAnt(Main.java:217)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

请注意堆栈跟踪中 MacroInstance 类(第 398 行)调用的方法。通过查看这一行的 Ant 代码,您可以看到一个 try-catch block ,它捕获由 fail 抛出的异常:

try {
c.perform();
} catch (BuildException ex) {
if (this.macroDef.getBackTrace()) {
throw ProjectHelper.addLocationToBuildException(ex, getLocation());
}

ex.setLocation(getLocation());
throw ex;
}

catch block 中,新异常 在以下行中抛出:

throw ProjectHelper.addLocationToBuildException(ex, getLocation());

这会导致忽略原始 BuildException 的退出代码。

更进一步,我们可以看到,如果启用了 this.macroDef.getBackTrace(),则会抛出此包装器异常。因此,解决问题的方法是将macrodef中的backtrace参数设置为false:

<macrodef name="ff" backtrace="false">
<sequential>
<fail message="some failure" status="3"/>
</sequential>
</macrodef>

关于java - macrodef 没有正确传达退出状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27470890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com