如何通过java程序运行ant命令?

时间:2013-08-23 06:06:54

标签: java ant shellexecute

我想通过java程序运行一个简单的ant -v命令。搜索之后,我知道我必须使用shell执行而不是进程,因为ant实际上不是exe格式。我有一个程序,用于执行简单的JAVAC命令,但ant永远不会工作。这是我的代码的样子。

Runtime runtime = Runtime.getRuntime() ;  
Process shellProcess = runtime.exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant -v") ;
shellProcess.waitFor() ;

运行此

时出现以下异常
Exception in thread "main" java.io.IOException: Cannot run program "D:\installs\apache-ant-1.9.2\bin\ant": CreateProcess error=193, %1 is not a valid Win32 application
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at java.lang.Runtime.exec(Runtime.java:615)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at com.check.SystemCheck.main(SystemCheck.java:14)
Caused by: java.io.IOException: CreateProcess error=193, %1 is not a valid Win32 application

指定整个路径的原因是,如果我没有,我得到文件未找到错误。 关于如何使这个工作的任何想法??

6 个答案:

答案 0 :(得分:3)

我突然想到了一些事情。

  1. {/ 1}} ant命令应该是{<1}}在windows
  2. 您应该将命令与参数分开,以便每个参数代表一个单独的ant.bat。这大大降低了包含空格的参数的复杂性,例如......
  3. 您应该真正使用String,这会降低使用ProcessBuilder
  4. 的复杂性

    例如......

    Process

    我还应该指出ProcessBuilder pb = new ProcessBuilder( "D:\\installs\\apache-ant-1.9.2\\bin\\ant.bat", "-v"); pb.redirectError(); // This should point to where your build.xml file is... pb.directory(new File("C:/")); try { Process p = pb.start(); InputStream is = p.getInputStream(); int in = -1; while ((in = is.read()) != -1) { System.out.print((char) in); } int exitValue = p.waitFor(); System.out.println("Exited with " + exitValue); } catch (Exception ex) { ex.printStackTrace(); } 是一个linux / unix shell脚本,Windows不知道该怎么做;)

    <强>更新

    我已经使用Windows 7和Java 7对此进行了测试,效果很好

    我使用Windows 7和Java 6对此进行了测试,效果很好......

    如果您确实在直接运行ant时遇到问题,则需要通过命令处理器运行批处理文件

    ant.bat

答案 1 :(得分:3)

Ant是用Java编写的。为什么不直接在同一个Java进程中调用它的类而不是启动外部进程?

发布了一个有趣的答案here

以下是答案中公布的代码:

File buildFile = new File("build.xml");
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());
p.init();
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.executeTarget(p.getDefaultTarget());

它将执行build.xml文件的默认目标。酷不是吗?

对我来说,主要优点是你可以更好地控制执行(例如,你可以很容易地知道某些事情是否失败),并且当然可以获得脚本将生成的输出。

答案 2 :(得分:0)

尝试

ArrayList<String> argList = new ArrayList<String>();
argList.add("-v");
String[] args = argList.toArray(new String[argList.size()]);
Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", args);

您还可以执行以下操作

ProcessBuilder pb = new ProcessBuilder("D:\\installs\\apache-ant-1.9.2\\bin\\ant -v", "-v");
Process p = pb.start();

答案 3 :(得分:0)

除了Aniket的答案之外,还要简化一些事情:

Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", new String[]{"-v"});

答案 4 :(得分:0)

可执行文件的参数必须单独传递:

Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", "-v");

在您的尝试中,可执行文件实际上是ant -v(即文件名中有空格,以dash v结尾)。

答案 5 :(得分:0)

我会跳过bat文件并直接运行启动器jar

File java = new File(new File(new File(
    System.getProperty("java.home"), "bin"), "java");
File antHome = new File("path to ant installation");
File launcher = new File(new File(antHome, "lib"), "ant-launcher.jar");
ProcessBuilder pb = new ProcessBuilder(
    java.getAbsolutePath(),
    "-jar",
    launcher.getAbsolutePath(),
    "-v");
pb.directory(dirContainingBuildXml);
Process p = pb.start();

但正如其他答案中所建议的那样,通过直接调用ant的Java API而不是使用外部进程,您可能会获得更好的结果。鉴于您在问题中的示例使用-v我假设您正在尝试从构建的详细输出中捕获某些内容。如果你通过它的API调用ant,你可以在Project上注册一个监听器,而ant会直接将日志消息传递给你的监听器,而不是你必须从流程输出中解析它们。