我想通过java程序运行一个简单的ant-v命令。经过搜索,我知道我必须使用shell execute而不是process,因为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:installsapache-ant-1.9.2binant": 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
指定整个路径的原因是,如果我不这样做,我会得到找不到文件的错误。你知道怎么做吗??
许多事情突然向我袭来。
- 在windows下,
ant
命令应为ant.bat
- 您应该将命令与参数分开,以便每个参数表示一个单独的
String
。这大大降低了包含空格的参数的复杂性,例如 - 你真的应该使用
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/unixshell脚本,Windows不知道该用它做什么;)
更新
我已经用Windows7和Java7测试过了,运行得很好
我已经用Windows7和Java6测试过了,效果很好。。。
如果直接运行ant.bat
仍然存在问题,则需要通过命令处理器运行批处理文件
ProcessBuilder pb = new ProcessBuilder(
"cmd",
"/c",
"D:\installs\apache-ant-1.9.2\bin\ant.bat",
"-v");
这里有一个有趣的答案。
以下是答案上的代码:
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将直接向侦听器传递日志消息,而不必从流程输出中解析它们。