繁体   English   中英

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

[英]How to run ant command through java program?

我想通过Java程序运行一个简单的ant -v命令。 搜索之后,我发现我必须使用shell execute而不是进程,因为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

指定整个路径的原因是,如果我不知道文件未找到错误。 关于如何使它工作的任何想法吗?

许多事情突然出现在我身上。

  1. ant.bat下的ant命令应为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<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();

除了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 (即,文件名中带有空格,并以破折号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会将日志消息直接传递给您的侦听器,而不必将它们从流程输出中解析出来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM