Как запустить команду Ant через Java-программу?
Я хочу запустить простую команду ant -v через Java-программу. После поиска я пришел к выводу, что знаю, что мне нужно использовать shell вместо execute, так как ant на самом деле не является exe-форматом. У меня есть программа, которая работает для выполнения простой команды JAVAC, но муравей никогда не работает. Вот как выглядит мой код.
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
Причиной указания всего пути является то, что если я не получаю файл, файл не найден. Любая идея о том, как заставить это работать??
6 ответов
Ряд вещей прыгает на меня.
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/unix, с которым 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");
Муравей написан на 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. Круто не так ли?
Для меня главное преимущество заключается в том, что вы можете лучше контролировать выполнение (например, легко узнать, что-то не получилось), и, конечно, можно получить результат, который сгенерирует скрипт.
В дополнение к ответу Аникета, чтобы сделать вещи еще проще:
Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", new String[]{"-v"});
Пытаться
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();
Параметры к исполняемому файлу должны быть переданы отдельно:
Runtime.getRuntime().exec("D:\\installs\\apache-ant-1.9.2\\bin\\ant", "-v");
В вашей попытке исполняемый файл буквально ant -v
(то есть с пробелом в имени файла и заканчивая тире v).
Я бы пропустил файл bat и сразу запустил флягу
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();
Но, как предлагается в других ответах, вы, вероятно, получите лучший результат, вызвав Java-интерфейс ant напрямую, а не используя внешний процесс. Учитывая ваш пример в вопросе использует -v
Я предполагаю, что вы пытаетесь захватить что-то из подробного вывода сборки. Если вы вызываете муравей через его API, вы можете зарегистрировать слушателя на Project
и ant будет доставлять сообщения журнала непосредственно вашему слушателю, а не анализировать их из вывода процесса.