【问题标题】:Ant places stacktraces in standard outputAnt 将堆栈跟踪放在标准输出中
【发布时间】:2015-08-19 17:07:51
【问题描述】:

我正在使用 Ant 以及我自己创建的任务。 当这些自定义 ant 任务失败时,它们的输出被重定向到标准输出。

我希望它们被重定向到标准错误。

一个简单的完整的通用 Ant 示例是:

<project name="test" default="init" basedir=".">

    <!-- Initialise project parameters -->
    <target name="init">
          <echo message="This is error message." level="error" />
    </target>
</project>

可以看到正确地将“这是错误消息”输出到标准错误:

Buildfile: /home/jll/Downloads/loggingerror.xml

init:
     [echo] Something wrong here.
     **[echo] This is error message.**

BUILD SUCCESSFUL
Total time: 0 seconds

粗体线在 Eclipse 中显示为红色,表示它在错误标准输出中。

现在当我运行我的自定义 ant 文件时:

<project name="test2" default="init" basedir=".">
    <taskdef resource="resource/customtasks.properties" />
    <target name="init" >

        <log
            scriptid="S4"
            message="Initialising Project Parameters."
            min="0"
            max="5"/>
    </target>
</project>

运行此程序预计会失败并出现 NullPointerException。

输出确实按预期显示:

Trying to override old definition of task import

init:
      [log] java.lang.NullPointerException
      .......
      [log]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
      [log]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      [log]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      [log]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      [log]     at java.lang.reflect.Method.invoke(Method.java:606)
      [log]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
      [log]     at org.apache.tools.ant.Task.perform(Task.java:348)
      [log]     at org.apache.tools.ant.Target.execute(Target.java:435)
      [log]     at org.apache.tools.ant.Target.performTasks(Target.java:456)
      [log]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
      [log]     at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
      [log]     at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
      [log]     at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
      [log]     at org.apache.tools.ant.Main.runBuild(Main.java:851)
      [log]     at org.apache.tools.ant.Main.startAnt(Main.java:235)
      [log]     at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
      [log]     at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

BUILD SUCCESSFUL
Total time: 0 seconds

但在这种情况下,一切都进入标准输出。为什么?

我在自定义任务中抛出异常的 Java 代码非常简单:

@Override
public void execute() throws BuildException {
    try {
        stuff....
    }
    catch (Exception e) {
        throw new BuildException(e);
    }
}

我也一直在尝试在我的 java 代码中摆弄 e.printStackTrace()logger.error("message", e),但到目前为止没有成功.即使要显示错误,行为也保持不变(所有内容都发送到标准输出)。

有什么方法可以看到我的堆栈跟踪显示,或者至少在 stderr 中显示某种错误消息?

谢谢

【问题讨论】:

  • 您好 jlengrand,您对此有什么解决方案吗?我也陷入了同样的问题。如果您找到任何解决方案,请提出建议。

标签: java logging ant stderr


【解决方案1】:

不认为这是可能的。

如果您没有太多类,最接近的解决方案是将每个类的输出重定向到一个文件 (stderr),方法是执行类似于所描述的操作 here.

但是他们也想重定向标准输出,但你可以试试这个:

<java classname="some.package.Class" output="stderr.txt"> ... </java>

然而,这并没有真正将它定向到 stderr,但它很接近。

【讨论】:

  • 感谢您的回答。你为什么说这在蚂蚁下是不可能的?我知道echo任务实现了这个,所以肯定是可以的吧?
  • 你试过stackoverflow.com/questions/8607536/… 吗?抱歉,您的问题比我最初意识到的要难。
  • 我的第一个示例表明 echo 确实可以毫无问题地输出到 stderr。我查看了任务的源代码,但没有看到确切的启用它。我也试图模仿这种行为,但到目前为止没有成功。
【解决方案2】:

您可以实现与 Echo 任务中相同的代码

import java.io.IOException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.ResourceUtils;
import org.apache.tools.ant.types.resources.LogOutputResource;
import org.apache.tools.ant.types.resources.StringResource;


public class MyLogTask extends Task {
    private String msg;

    public void execute() throws BuildException {
        try {
            ResourceUtils.copyResource(new StringResource(msg), new LogOutputResource(this, Project.MSG_ERR),
                                  null, null, false, false, true, null, null, getProject(), true);
        } catch (IOException ioe) {
            throw new BuildException(ioe, getLocation());
        }
    }

    public void setMessage(String msg) {
        this.msg = msg;
    }
}

然后消息转到stderr

<project default="main">

    <taskdef name="mylog" classname="MyLogTask"/>

    <target name="main">
        <echo message="ERROR" level="error" />
        <mylog message="hello"/>
    </target>

</project>

这是测试:

/cygdrive/c/temp/ant>ant 
Buildfile: c:\temp\ant\build.xml

main:
     [echo] ERROR
    [mylog] hello

BUILD SUCCESSFUL
Total time: 0 seconds
/cygdrive/c/temp/ant>ant 2>err
Buildfile: c:\temp\ant\build.xml

main:

BUILD SUCCESSFUL
Total time: 0 seconds
/cygdrive/c/temp/ant>

【讨论】:

  • 嗯,这里真正有趣的是我的消息根本没有显示在堆栈中。如果我使用这种方法,它就不存在了:S
  • 如果你使用 MyLogTask 会显示消息吗?
  • 是的。我认为它可能来自我的记录器配置。但我很难找到到底是什么
  • 好的,现在我明白了。我的任务是调用其他 java 类。我遇到的 NullPointerException 发生在比我的任务更深的类中,它们自己处理错误(并执行 e.prinstacktrace)。所以我的 Ant 任务永远不会捕获异常。那些内部类的错误是怎么出现在stdout里的?
  • 好吧,如果他们调用 printstacktrace,那么它会转到标准输出。您可以更改您的设计,以便处理所有异常是您的主要任务
猜你喜欢
  • 2012-09-05
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多