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

我想通过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

 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 

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

我突然想到了一些事情。

  1. ant命令应该是ant.bat下的ant.bat
  2. 您应该将命令与参数分开,以便每个参数代表一个单独的String 。 这大大降低了包含空格的参数的复杂性,例如……
  3. 你应该真的使用ProcessBuilder ,它会降低使用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(); } 

我还应该指出, ant是一个linux / unix shell脚本,Windows不知道该怎么做;)

更新

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

我用Windows 7和Java 6测试了这个,效果很好……

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

 ProcessBuilder pb = new ProcessBuilder( "cmd", "/c", "D:\\installs\\apache-ant-1.9.2\\bin\\ant.bat", "-v"); 

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

这里有一个有趣的答案。

这是在答案上发布的代码:

 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文件的默认目标。 酷不是吗?

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

尝试

 ArrayList argList = new ArrayList(); 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(); 

除了Aniket的答案之外,还要简化:

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

必须分别传递可执行文件的参数:

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

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

我会跳过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将直接将日志消息传递给侦听器,而不必将其解析为进程输出。