简体   繁体   English

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

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

I want to run a simple ant -v command through a java program. 我想通过Java程序运行一个简单的ant -v命令。 After searching, I came to a point where I know I have to use shell execute instead of process, since ant is not really an exe format. 搜索之后,我发现我必须使用shell execute而不是进程,因为ant并不是真正的exe格式。 I have a program that works for executing simple JAVAC command, but ant never works. 我有一个可以执行简单的JAVAC命令的程序,但是ant永远无法工作。 Here is what my code looks like. 这是我的代码的样子。

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

I get following exception when I run this 运行此程序时出现以下异常

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

The reason for specifying the whole path is, if I don't I get file not found error. 指定整个路径的原因是,如果我不知道文件未找到错误。 Any idea on how to get this working?? 关于如何使它工作的任何想法吗?

A number of things jump out at me. 许多事情突然出现在我身上。

  1. The ant command should be ant.bat under windows ant.bat下的ant命令应为ant.bat
  2. You should separate the command from the arguments, so that each argument represents a separate String . 您应该将命令与参数分开,以便每个参数代表一个单独的String This greatly reduces the complexity of arguments that contain spaces, for example... 例如,这大大降低了包含空格的参数的复杂性。
  3. You should really use ProcessBuilder , it will reduce the complexity of using Process 您应该真正使用ProcessBuilder ,它将减少使用Process的复杂性

For example... 例如...

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

I should also point out that ant is a linux/unix shell script, which Windows won't know what to do with ;) 我还应该指出, ant是一个linux / unix shell脚本,Windows不会使用它;)

Updated 更新

I've tested this using Windows 7 and Java 7, works just fine 我已经使用Windows 7和Java 7进行了测试,效果很好

I've tested this using Windows 7 and Java 6, works just fine... 我已经使用Windows 7和Java 6进行了测试,效果很好...

If you do continue to have issues running the ant.bat directly, then you will need run the batch file via the command processor 如果确实仍然存在直接运行ant.bat问题,那么您将需要通过命令处理器运行批处理文件

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

Ant is written in Java. Ant是用Java编写的。 Why not directly call its classes in the same Java process instead of launching an external process? 为什么不在同一Java进程中直接调用其类,而不是启动外部进程?

There was an interesting answer posted here . 这里发布一个有趣的答案。

Here is the code as posted on that answer: 这是该答案上发布的代码:

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

It will executed the default target of the build.xml file. 它将执行build.xml文件的默认目标。 Cool isn't it? 是不是很酷

For me, the main advantage is that you can control the execution better (you can easily know if something failed for example) and it is of course possible to get the output the script would generate. 对我来说,主要优点是您可以更好地控制执行(例如,您可以轻松知道是否发生了故障),并且当然可以获取脚本将生成的输出。

Try 尝试

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

You can also do the following 您还可以执行以下操作

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"});

Parameters to the executable must be passed in separately: 可执行文件的参数必须单独传递:

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

In your attempt, the executable file is literally ant -v (ie with a space in the filename and ending with dash v). 在您尝试执行的过程中,可执行文件实际上是ant -v (即,文件名中带有空格,并以破折号v结尾)。

I would skip the bat file and run the launcher jar directly 我将跳过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();

But as suggested in other answers you'll probably get a better result by calling ant's Java API directly rather than using an external process. 但是,正如其他答案所建议的那样,通过直接调用ant的Java API而不是使用外部进程,可能会获得更好的结果。 Given your example in the question uses -v I presume you're trying to capture something from the verbose output of the build. 给定您问题中使用-v的示例,我想您正在尝试从构建的详细输出中捕获某些内容。 If you invoke ant via its API you can register a listener on the Project and ant will deliver log messages directly to your listener rather than you having to parse them out of the process output. 如果您通过其API调用ant,则可以在Project上注册一个侦听器,并且ant会将日志消息直接传递给您的侦听器,而不必将它们从流程输出中解析出来。

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

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