【问题标题】:How to run ant command through java program?如何通过java程序运行ant命令?
【发布时间】:2013-08-23 06:06:54
【问题描述】:

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

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

【问题讨论】:

    标签: java ant shellexecute


    【解决方案1】:

    我突然想到了很多事情。

    1. windows下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.bat 是一个批处理文件,ProcessBuilder 不知道如何处理(这是错误 193 - java 只能执行 .exe 文件,而不是 .bat )。
    • @IanRoberts 实际上,对我来说工作得很好,这是我在 Windows 7 机器上测试的代码...
    • @IanRoberts 在 Windows 7 上使用 Java 6 成功测试
    【解决方案2】:

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

    对我来说,主要优点是您可以更好地控制执行(例如,您可以轻松知道是否发生了故障),当然也可以获得脚本生成的输出。

    【讨论】:

      【解决方案3】:

      试试

      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();
      

      【讨论】:

      • 从 java 1.5 开始你就不需要数组了——现在是可变参数
      【解决方案4】:

      除了 Aniket 的回答,让事情变得更简单:

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

      【讨论】:

      • ant 是一个shell 脚本,它在windows 下不起作用。而varargs 会更简单 - 恕我直言
      【解决方案5】:

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

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

      在您的尝试中,可执行文件的字面意思是 ant -v(即文件名中有一个空格并以破折号 v 结尾)。

      【讨论】:

      • @MadProgrammer 有ant for windiws - 这行不通吗?
      • 是的,但是ant 命令实际上是ant.bat,而不是ant,因此出现错误CreateProcess error=193, %1 is not a valid Win32 application,因为Windows 正在尝试启动ant shell 脚本
      • 这不是真的。您不必必须这样做,即使您不单独传递参数,参数也可以正常工作,如果您注意转义的话。
      • @eis 不是 AFAIK。我知道它在 Linux 中不起作用。 Windows 我认为它也不起作用。你有什么特别需要做的吗,如果他使用ant.bat,你是说OP代码有效吗?
      • @Bohemian 它仍然无法工作,但由于其他原因(请参阅my answer)。至少在 windows 中你不必分离参数,尽管分离它们可能是一个好习惯。
      【解决方案6】:

      我会跳过 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 会直接将日志消息传递给您的侦听器,而不是您必须将它们从进程输出中解析出来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 2016-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多