пятница, 8 июля 2011 г.

Запуск Ant из Java

Всем привет! Thanks God it`s Friday! Пора разбавить скучные трудовые будни написанием маленького поста. Путем голосования и единогласного выбора было решено писать про использование ant в java :-)

 
Когда я кому-то что-то объясняю, обычно начинаю с паразитарной фразы: "Все очень просто", но сегодня не тут случай. Работать с ant в java не просто, а очень просто, ща расскажу как.

Для работы с ним нам понадобятся библиотеки которые можно найти в папке /lib в домашней директории "муравья", там их около 20. Главным элементом, который и выполняет вызов анта, является библиотека ant-launcher.jar, которой в свою очередь нужно api из библиотеки ant.jar и ant-contrib.jar, содержащей основные команды (например mkdir, echo  и др) для корректного выполнения таргетов. Итого плюс три зависимости в classpath. Остальные же библиотеки выступают в роли расширения возможностей, например библиотеки для работы с ssh, junit, javamail, организацией логирования через log4j и др. Наверняка даже можно найти и пользовательские расширения анта.

Для того чтобы сказать анту запустить существующий xml, нужно проделать следующие операции:

Project project = new Project();
File antFile = new File(filename);
project.setUserProperty("ant.file", antFile.getAbsolutePath());
project.init();
ProjectHelper helper = ProjetctHelper.getProjectHelper();
helper.parse(project, antFile);
project.executeTarget(project.getDefaultTarget());

Хмл фаил:

<project name="AntTest" basedir="." default="test">
    <property name="message" value="Hello, ant!"/>
    <target name="test">
        <echo message="${message}"/>
    </target>
</project>

Если у нас есть несколько проектов, можно скопировать properties из одного в другой, вызов метода copyUserProperties(project), делает как раз то я о чем я написал целых 26 слов и предлогов.
Вызов метода executeTarget() приводит к выполнению таргета, имя которого метод получает в качестве параметра. В нашем случаем мы запускаем таргет, заданный по умолчанию.К сожалению, сообщения Hello, Ant! мы не увидим, так как стандартный поток вывода анта ничего не знает о нашем стандартном потоке вывода в консоль. Исправить это можно добавив объект BuildListener.

DefaultLogger logger = new DefaultLogger();
logger.setErrorPrintStream(System.err);
logger.setOutputPrintStream(System.out);
logger.setMessageOutputLevel(Project.MSG_INFO);
project.addBuildListener(logger);

test:
     [echo] Hello, ant!

Так же можно передать анту на вход параметры, с помощью метода

project.setProperty("message", "Hello, ANT!!!");

Таким образом ант сначала проверяет наличие свойства message, если находит (как в нашем случае) он его заменяет. Теперь на выходе мы получим:

test:
     [echo] Hello, ANT!!!

По-моему чего-то не хватает...ах да, не хватает сообщения  о том, с каким результатом у нас завершился билд. Для этого нужно вызвать метод

project.fireBuildFinished(null);

на вход которому можно передать экземпляр ошибки, которая проявится в случае не успешного выполнения, а можно и null.

Теперь немного поговорим о модификации ант файла. В ант api есть класс Target, который выступает в роли объектно представления таргета из ант файла, имеющий набор команд для запуска, представленных абстрактным классом Task. Думаю нет смысла рассказывать о всех имеющихся в анте тасках, если для этого есть javadoc, который, кстати, лежит здесь.

Вот в принципе и все, для начала сойдет. Важно не забывать, что программно можно делать все то, что можно делать и декларативно, в xml файле. Другой вопрос насколько это будет правильно и удобно? Решать вам, но заморачиваться на программном конфигурировании не стоит, ведь зачем тогда использовать ант?

3 комментария:

  1. вроде как ошибочка
    вместо
    "helper.executeTarget(project.getDefaultTarget());" наверно надо
    "project.executeTarget(project.getDefaultTarget());"

    ОтветитьУдалить
  2. и ещё я столкнулся с проблемой, когда вылетал такой экссепшен.

    Unable to find a javac compiler;
    com.sun.tools.javac.Main is not on the classpath.
    Perhaps JAVA_HOME does not point to the JDK.

    убил уйму времени что бы найти решение. Везде пишут про "add the tools.jar from JDK/lib to the classpath for Ant in Eclipse."
    Ничего не помогало. В итоге эту самую tools.jar надо подкинуть к тем трем библиотекам ant которые мы используем.

    ОтветитьУдалить