可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to run a simple ant -v command through a java program. 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. I have a program that works for executing simple JAVAC command, but ant never works. 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??
回答1:
A number of things jump out at me.
- The
ant
command should be ant.bat
under windows
- You should separate the command from the arguments, so that each argument represents a separate
String
. This greatly reduces the complexity of arguments that contain spaces, for example...
- You should really use
ProcessBuilder
, it will reduce the complexity of using 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 ;)
Updated
I've tested this using Windows 7 and Java 7, works just fine
I've tested this using Windows 7 and Java 6, works just fine...
If you do continue to have issues running the ant.bat
directly, then you will need run the batch file via the command processor
ProcessBuilder pb = new ProcessBuilder(
"cmd",
"/c",
"D:\\installs\\apache-ant-1.9.2\\bin\\ant.bat",
"-v");
回答2:
Ant is written in Java. Why not directly call its classes in the same Java process instead of launching an external process?
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. 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.
回答3:
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();
回答4:
In addition to Aniket's answer, to make things even simplier:
Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", new String[]{"-v"});
回答5:
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).
回答6:
I would skip the bat file and run the launcher jar directly
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. Given your example in the question uses -v
I presume you're trying to capture something from the verbose output of the build. 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.