jlengrand
jlengrand

Reputation: 12827

Ant places stacktraces in standard output

I am using Ant, together with tasks I have created myself. When those custom ant tasks fail, their output is redirected to stdout.

I want them to be redirected to stderr.

A simple full generic Ant example is :

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

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

which properly outputs "This is error message" to stderr as can be seen :

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

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

BUILD SUCCESSFUL
Total time: 0 seconds

The line in bold shows as red in Eclipse, which indicates it is in the error standard output.

Now when I run my custom ant file :

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

Running this is expected to fail with a NullPointerException.

The output indeed shows as expected :

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

But in this case, everything goes to stdout. Why?

My Java code to throw exceptions in my custom tasks is really simple :

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

I have also been trying to fiddle with e.printStackTrace() and logger.error("message", e) in my java code, without success so far. The behavior stays the same (everything sent to stdout) even though the errors to show.

What would be a way to see my stacktraces showing up, or at least some kind of errors message in stderr?

Thanks

Upvotes: 2

Views: 1618

Answers (2)

Oleg Pavliv
Oleg Pavliv

Reputation: 21172

You can implement the same code as in Echo task

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;
    }
}

Then the message goes to stderr

<project default="main">

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

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

</project>

Here is the test:

/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>

Upvotes: 1

ozborn
ozborn

Reputation: 1070

It's don't think it's possible.

The closest solution if you don't have too many classes is to redirect the output for each class to a file (stderr) by doing something similar to what was described here.

However they also wanted to redirect stdout, but you can try this:

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

However this isn't really directing it to stderr, but it's close.

Upvotes: 2

Related Questions