是否可以显示ant扩展点的调用“图形”?

时间:2011-08-02 08:22:55

标签: ant

我在ant中定义了一个扩展点:

<extension-point name="foo"/>

许多任务在几个导入的ant文件中都有助于这一点:

<bindtargets targets="bar" extensionPoint="foo" />

然而,我确切地想知道哪些任务正在起作用。有没有办法让ant报告由给定扩展点触发的任务?更常见的是,有没有办法显示蚂蚁任务的“调用图”(或简称依赖项列表)?

我尝试使用ant(-v等)的详细选项,没有运气。

由于

3 个答案:

答案 0 :(得分:0)

首先,您可以尝试使用远程调试在IDE中调试ANT进程,方法是向ANT_OPTS添加一些参数(我的设置在〜/ .profile中):

  

http://blog.dahanne.net/2010/06/03/debugging-any-java-application/

分析可能会有所帮助。我在ANT Wiki上发现了Antro项目...

  

http://sourceforge.net/projects/antro

也许你可以尝试一下。该项目据说是为ANT设计的,看起来很有希望解决您的问题。

您还可以使用Yourkit Java Profiler进行CPU分析。 YJP可以显示java应用程序的调用图,但我不确定是否可以找出哪些是ANT目标。

以下文档显示了如何使用YJP代理启动Java应用程序。

  

http://www.yourkit.com/docs/95/help/agent.jsp

答案 1 :(得分:0)

我知道有两种获取此信息的方法:

  1. 您可以从Ant的控制台记录器中获取有效的目标/扩展点调用序列。为此,通过将命令行上的-verbose传递给Ant,将Ant的日志记录工具置于详细模式。有两行,一个接一个,在大多数目标之前立即转储到控制台,因为它们在构建脚本中被调用:

    • 一行,显示以文字Build sequence for target(s) 'artifact' is [...]开头的调用序列中的目标摘要。
    • 显示详细调用序列的行(包含嵌套目标和antcalls)。这一行以文字Complete build sequence is [...]开头。此列表尽可能合理地考虑对该行记录到控制台时列出的每个目标的任何ifunless属性的评估。

    只需调用您的Ant版本,就像通常使用-verbose选项一样,您的控制台应该具有您正在寻找的信息。

  2. 您可以使用名为Grand的工具获取呼叫序列的图形表示。但是,它已经很长时间没有更新,因此不支持扩展点(这是你在这里所关注的)。它将解释antcall'santdepend'encies。它没有评估ifunless属性,只是简单地识别潜在的执行顺序 - 更多的依赖层次结构而不是实际的调用图。该项目在Github上,因此支持扩展点的更新可能不会太困难。

    使用 Graphviz

  3. 呈现图形

    对于实际的通话顺序,请使用选项1。

答案 2 :(得分:0)

这很邋,,但它确实有效。 Ant实际上非常容易编写脚本,如果您至少使用Java 6(或者它可能是Java 7),则内置了javascript支持,因此可以直接使用。这定义了一个任务,它将回调调用顺序中任何目标的依赖关系:

<scriptdef name="listdepends" language="javascript">
    <attribute name="target"/>
    <![CDATA[
        var done = [];
        var echo = project.createTask("echo")
        function listdepend(t) {
            done.push(t.getName());
            var depends = t.getDependencies();
            while (depends.hasMoreElements()) {
                var t2 = depends.nextElement();
                if (done.indexOf(t2)==-1) listdepend(project.getTargets().get(t2));
            }
            echo.setMessage(t.getName());
            echo.perform();             
        }
        var t = attributes.get("target");
        if (t!=null) {
            var targ = project.getTargets().get(t);
            listdepend(targ);
        }
    ]]>
</scriptdef>

在您的情况下,您可以创建一个新目标(或不创建)并像这样调用它:

    <target name="listfoo">
        <listdepends target="foo"/>
    </target>

正如我所说,这有点草率。它可能不是很快(虽然除非你的目标触发成千上万的其他目标,但它可能并不明显很慢)。它不会处理antcall任务(尽管可以修改它以便轻松完成)或响应if和unless属性。如果依赖关系嵌套得太远,它可能会达到递归深度限制(但我怀疑任何项目都将它们嵌套得足够深)。

该数组用于确保每个依赖项都列出一次(ant只运行一次)。