Из жизни насекомых: сборщик Ant в Java-проектах

Из цикла "Java + консоль"В статьях под рубрикой Java-практикум постоянно упоминается сборщик Ant. В русской википедии об этой программе написано достаточно скупо.  Хочу немного восполнить этот пробел.

Сборщик - главный инструмент программиста. Можно было бы возразить, сказав, что таковым является компилятор, но без выполнения огромного количества вспомогательных рутинных операций (копирование и преобразование файлов, упаковка их в библиотеки, очистка временных директорий, выгрузка на удаленный сервер и многое другое) успешная компиляция немногого стоит.

Начать хочу издалека, с классического сборщика make, до сих пор являющегося стандартом де факто при сборке программного обеспечения для Linux из исходников. Этот простой, старый и при этом могучий инструмент до сих пор не утратил своей актуальности. Я пользовался make до недавнего времени, хотя о существовании ant знал с 2002 года. Потребность разобраться с ant возникла в связи с необходимостью использования IDE Eclipse, с которой я экспериментировал прошлым летом. Сама эта среда разработки показалась мне черезчур громоздкой и неадекватной для тех небольших программ, которые я пишу. А вот вынужденное знакомство с синтаксисом ant, являющимся сборщиком по умолчанию в этой IDE, оказалось очень полезным.

Первое отличие ant от make - способ хранения файла, ответственного за сборку. В первом случае это обычный текстовой файл, синтаксис которого сродни скрипту для интерпретатора bash. Файл для make должен называться (по умолчанию) Makefile и находиться (как правило) в той директории, из которой запускается команда. В случае с ant порядок сборки описывается в файле build.xml, причем, как явствует из названия файла, используется синтаксис xml.

Рассмотрим простейший файл для сборки.

<?xml version="1.0"?>
<project default="all">
    <property name="packagename" value="LAB3F"/>
    <target name="all" depends="clean">
        <mkdir dir="../output/${packagename}"/>
    </target>
    <target name="clean">
        <delete dir="../output/${packagename}" />
    </target>
</project>

Этот файл дан для примера и не делает никакой полезной работы. Если в каталоге, где он лежит, ввести команду ant, то сборщик сначала удалит директорию ../output/LAB3F, если таковая имеется, а затем вновь ее создаст. Однако принцип построения файла, думаю, понятен: в нем объявлена переменная (элемент property) и две метки (элементы target), обращаясь к которым можно выполнить ту или иную задачу. В частности, если набрать в консоли команду ant clean, то вышеуказанная директория будет удалена. Если набрать ant all - она будет удалена и вновь создана. В данном случае ant all - избыточная конструкция, поскольку сборщик при вызове команды без аргументов обращается к метке по умолчанию (см. атрибут default элемента project), а это как раз и есть all.

Обратите внимание на атрибут depends первого элемента target. Он свидетельствует о том, что прежде будет выполнено задание с меткой clean. Оперируя такими зависимостями, можно строить цепочки из взаимосвязанных заданий, делая структуру файла build.xml более прозрачной.

Ant написан на Java и, следовательно, одинаково успешно работает и под Linux, и под Windows. Нетрудно догадаться, что большинство консольных утилит JDK реализовано в ant в виде заданий: javac, jar, native2ascii и т.п. Вот, например, как откомпилировать классы, находящиеся в текущей директории, с помощью ant:

        <javac srcdir="." destdir="../../_classes">
            <classpath>
                <pathelement path="../../_classes"/>
                <pathelement path="../../_classes/mailapi.jar"/>
            </classpath>
        </javac>

Выполняя это задание, сборщик многое выполнит самостоятельно (например, создаст недостающие каталоги в соответствии с полным именем класса). Приведу несколько интересных примеров стандартных заданий ant:

  <tar destfile="../../_backup/test.tgz" compression="gzip" basedir="." includes="**"/>

  - архивирование текущей директории с компрессией с помощью алгоритма tar;

  <get src="http://test.com/test.html" dest="docs/test.html"/>

  - скачивание удаленного файла по http;
 
  <ftp server="ftp.apache.org"
       userid="anonymous"
       password="me@myorg.com">
    <fileset dir="htdocs/manual"/>
  </ftp>

  - выгрузка файлов по ftp.

Обратите внимание, что в отличие от make, ant не требует наличия на машине соответствующих консольных утилит, а значит даже на Windows-машине, где нет таких программ, как tar и wget эти задания будут выполнены.

Как запустить утилиту, не предусмотренную в сборщике? Очень просто, с помощью задания exec. Например, в следующем примере ant
вызывает потоковый редактор sed чтобы на основании некоего шаблона создать css-файл для проекта:

  <exec executable="sed" output="client/index.css">
   <arg line='-e "s/DARK1/#0044FF/" ../../TEMPLATE/index.css'/>
  </exec>

Другой способ выполнения нестандартных заданий ant - поиск в Интернете готовых решений от сторонних разработчиков (о некоторых из них я писал в предыдущих статьях рубрики) или написание собственных, благо ant предоставляет для этого необходимый API.

Теперь немаловажный вопрос: как установить ant на Linux-машину? Ведь этот сборщик распространяется в виде тарбола и никакие заклинания типа "apt-get" не помогут. Сделать нужно вот что. Распаковать архив и всё содержимое каталога lib скопированть в $JAVA_HOME/jre/lib/ext, где JAVA_HOME - директория, где у вас лежит JDK или JRE. Теперь в каталоге bin  тарбола найдите скрипт ant, в начале его пропишите JAVA_HOME={путь, по которому у вас можно найти JDK}, сохраните, скопируйте отредактированный скрипт в /usr/bin и всё, можно запускать ant из любой директории, где есть build.xml.

 

 

хех  на счет   установки я

хех  на счет   установки я делаю как в мануале написано  далее проблем можно избежать если используешь несколько версий jdk :)

Создаю скрипт в нем переменную $ANT_HOME   далее пихаю ее в $PATH,  а  lib-ы  в  $CLASSPATH

что то типа этого

export JAVA_HOME=/usr/local/jdk-1.4.02 export ANT_HOME=/usr/local/ant
export PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin
export CLASSPATH=$CLASSPATH:$ANT_HOME/lib 

 и  смотря какой jdk тебе нужен  выбераешь нужный скрипт и его запускаешь :) :) :)

Грамотно. Я, честно говоря,

Грамотно. Я, честно говоря, мануал по установке ant даже не читал :).

Не очень представляю в какой ситуации сборщик может потребоваться запускать со старой версией JDK. Если для генерации байткода в прежнем формате (для мидлетов, например), то можно использовать опцию target="1.3" задания javac. Я стараюсь пользоваться только одной версией JDK - поближе к самой свежей (усли уж не 1.6.0_10, то хотя бы 1.6.0_6). Хотя проблемы несовместимости (когда более новая Java не работает со старым кодом) бывали-с, бывали-с. Поскольку в моей практике необходимость использовать старые JDK встречается редко, устанавливаю их лишь в случае необходимости, а решив проблему сразу удаляю. Чтобы энтропии не было. Я с ней борюсь :).

Понравилась статья, спасибо!

Понравилась статья, спасибо! http://www.enterra.ru/blog/automation_builds_android_applications/ тоже неплохо написано в тему.

Отправить комментарий

КАПЧА
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
CAPTCHA на основе изображений
Enter the characters shown in the image.