Why does ant.bat not return an error status when r

2019-04-06 01:18发布

When I run ant from the command-line, if I get a failure, I get a non-zero exit status ($? on UNIX, %ERRORLEVEL% on Windows). But we have a Java program which is running ant (through ProcessBuilder), and when ant fails, on Windows we cannot get the exit status.

I just verified this with this simple ant test file:

<project name="x" default="a">
  <target name="a">
    <fail/>
  </target>
</project>

On UNIX, running ant prints a failure message, and echoing $? afterward prints 1. On Windows, running ant or ant.bat prints a failure message, and echoing %ERRORLEVEL% afterward prints 1.

Now, using the test program below: On UNIX, java Run ant prints a failure message, and echoing $? afterward prints 1. On Windows, java Run ant can't find a program named ant to run, but java Run ant.bat prints a failure message, yet echoing %ERRORLEVEL% afterward prints 0. What gives?

We're relying on being able to check the exit status after running ant. We were, anyway. Why can't we rely on this, programmatically?

Test program:

import java.io.*;

public class Run {
  public static void main(String[] args) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder(args);
    Process p = pb.start();
    ProcThread stdout = new ProcThread(p.getInputStream(), System.out);
    ProcThread stderr = new ProcThread(p.getErrorStream(), System.err);
    stdout.start();
    stderr.start();
    int errorLevel = p.waitFor();
    stdout.join();
    stderr.join();
    IOException outE = stdout.getException();
    if (outE != null)
      throw(outE);
    IOException errE = stdout.getException();
    if (errE != null)
      throw(errE);
    System.exit(errorLevel);
  }

  static class ProcThread extends Thread {
    BufferedReader input;
    PrintStream out;
    IOException ex;

    ProcThread(InputStream is, PrintStream out) {
      input = new BufferedReader(new InputStreamReader(is));
      this.out = out;
    }

    @Override
    public void run() {
      String line;
      try {
        while ((line = input.readLine()) != null)
          out.println(line);
      } catch (IOException e) {
        setException(e);
      }
    }

    private void setException(IOException e) {
      this.ex = e;
    }

    public IOException getException() {
      return ex;
    }
  }
}

标签: java ant exec fork
8条回答
ゆ 、 Hurt°
2楼-- · 2019-04-06 01:39

This is a long-standing issue for older versions of Ant on Windows. I believe it has been fixed in version 1.7.0.

See this bug for details and this discussion for an approach to address it.

查看更多
狗以群分
3楼-- · 2019-04-06 01:49

I solved this problem by creating two extra batch files (not very nice, but it works):

Content of file myant.bat:

call ant2.bat %*

Content of file ant2.bat:

call ant.bat %*
if errorlevel 1 (goto ERROR_EXIT)
exit /B 0
:ERROR_EXIT
exit /B 1

Now I can call myant.bat as a Process from java and I get the correct exit value.

Sorry, I cannot say why this works. It's simply the result of a many many tries.

查看更多
登录 后发表回答