2

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

jlengrand
  • 12,152
  • 14
  • 57
  • 87
  • Hi jlengrand, do you get any solution for this? I am also stuck in the same problem..please suggest, if you find out any solution. – Manish Agrawal Jan 08 '16 at 07:18

2 Answers2

2

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.

Community
  • 1
  • 1
ozborn
  • 980
  • 5
  • 24
  • Thanks for the answer. Why are you saying this is not possible under ant? I know that the echo task achieves this, so it must be possible, isnt it? – jlengrand Jun 04 '15 at 22:19
  • Did you try http://stackoverflow.com/questions/8607536/ant-exec-redirecting-standard-out-but-not-standard-error ? Sorry, your problem is harder than I first realized. – ozborn Jun 04 '15 at 22:25
  • My first example sows that echo indeed does output to stderr without problem. I have looked at the source code of the task, without seeing exactly enables it. I have also tried to mimic the behaviour, without success so far. – jlengrand Jun 04 '15 at 22:34
1

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>
Oleg Pavliv
  • 20,462
  • 7
  • 59
  • 75
  • Hum, what's really interesting here is that my message doesn't show at all in the stack. It just isn't there if I use this method :S – jlengrand Jun 05 '15 at 07:23
  • If you use MyLogTask does it display the message? – Oleg Pavliv Jun 05 '15 at 07:26
  • Yes. I think it might come from my logger configuration. But I am in pain to find what exactly – jlengrand Jun 05 '15 at 07:30
  • Ok, so now I get why. My task is calling other java classes. The NullPointerException that I meet happens in classes level deeper than my task, and they handle the error themselves (and do a e.prinstacktrace). So my Ant task never catches the exception. How is it that the errors of those inner classes appear in stdout? – jlengrand Jun 05 '15 at 07:46
  • Well, if they call printstacktrace then it goes to stdout. You may change your design so that it's your main task who handles all exceptions – Oleg Pavliv Jun 05 '15 at 07:51
  • You are right. If I throw an Exception at higher level, everything works as expected. Is there not way to avoid inner levels stacktraces to be redirected? – jlengrand Jun 05 '15 at 07:59
  • Not that I know. Even if I do System.err.println() it goes to stdout – Oleg Pavliv Jun 05 '15 at 08:35